Reputation: 8246
I've worked so far with SVN, GIT and Mercurial, for the latter two the workflow always consisted just of pull / merge / push. Now I'm working on a project where the workflow involves rebasing often from parent branch and I'm not sure I understand entirely what is happening or if my workflow is the right one. I'm doing all of my work in a designated branch, so:
git checkout dvl_bkend // This is 'parent' branch
git checkout -b dvl_bogdan // Created my own branch
Now all of below from my own branch. As I start a coding session:
git pull --rebase -s recursive -X ours origin dvl_bkend
Do coding and stuff, as soon as I have something stable-ish
git add stuff
git commit stuff
// rinse and repeat above two steps
Now when I have something ready for push.
git pull --rebase -s recursive -X ours origin dvl_bkend
At this point I would want to push to my dvl_bogdan but I can't saying that I need to pull first. So I:
git pull origin dvl_bogdan
Now this gives me conflicts that I need to merge (no ideea why this is happening?) and at this point I'm guessing something is not right. Anyway if I resolve conflicts I can then:
git push origin dvl_bogdan
Repeat all steps above until I'm ready for a pull request. Then repeat them some more. Where am I messing up with my flow? I've somehow managed to get in a situation where rebasing kept applying duplicate commits:
bogdan 5b31717 Merge branch 'develop_bogdan' of xx into develop_bogdan 8 May 2013
Bogdan Neacsa 810d753 Updated payment service to recieve an Account entity now rather that creating it itself. Also change… 8 May 2013
bogdan 429f97b Fix to model and service in payments. Quick fix to tests after changes. 8 May 2013
Bogdan Neacsa 7c6ff32 Updated payment service to recieve an Account entity now rather that creating it itself. Also change… 8 May 2013
bogdan d74ce5a Fix to model and service in payments. Quick fix to tests after changes. 8 May 2013
Bogdan Neacsa 8ab401e Updated payment service to recieve an Account entity now rather that creating it itself. Also change… 8 May 2013
bogdan 259349b Fix to model and service in payments. Quick fix to tests after changes. 8 May 2013
Thanks, Bogdan
EDIT: ------------ part unclear to me -------------------
So I'm on my dvl_bogdan branch, and it's synced with me remote branch, that is if I do:
git pull origin dvl_bogdan
This states I'm up to date. Now I do:
git pull --rebase -s recursive -X ours origin dvl_bkend
And this does not give me any conflicts. But now when I try:
git push origin dvl_bogdan
It asks me to do a pull before I can push and this pull will give me conflicts. I can't really understand what is going one here.
Upvotes: 0
Views: 354
Reputation: 26555
Expicitly on the unclear part:
git pull origin dvl_bogdan
This will do a git fetch
, which updates origin/dvl_bogdan and a git merge
, which tries to apply all changes from origin/dvl_bogdan to your local dvl_bogdan. If it tells you, you are up to date. Then no one else pushed on that branch. (As expected as it seems you intend to work on this branch alone.)
git pull --rebase -s recursive -X ours origin dvl_bkend
This will do again a git fetch
to update origin/dvl_bkend. Then a rebase will copy all your changes and apply them to origin/dvl_bkend. The resulting branch is completely unrelated to your dvl_bogdan. Use gitk origin/dvl_bogdan...dvl_bogdan
now to see your situation:
You have a common base, on which there is one branch(1) with your original commits ending on origin/dvl_bogdan and another branch(2) with contains changes from dvl_bkend with the copies of your changes on top.
git push origin dvl_bogdan
Now you try to push the branch(2) to branch(1), which does not work as this is no fast forward push.
To solve this, face the fact that origin/dvl_bkend and origin/dvl_bogdan are two different, already published branches. You need to merge both with a merge commit, use git fetch && git merge origin/dvl_bkend
or simply git pull
, which is doing exactly the same.
Alternatively it is possible to do a force push to update dvl_bogdan anyway, but be really sure you know what you are doing in this case.
Upvotes: 1
Reputation: 26555
The general idea sounds perfectly fine. A few comments:
A local branches is able to track its corresponding remote upstream branch. Setting an upstream branch is always a good idea, as it is the default for many operations like push and pull. Use git branch -vv
to see which local branches you have and which remote branch they track.
Rebasing is changing history. Never change history you already published. This will lead to duplicate commit entries otherwise. A correctly set upstream helps you with that.
Set git config push.default
to a good value. (see git help config
) I would recommend "current" or "simple" if you have a recent git version.
Be sure you understand the meaning of "-s recursive -X ours". It might ignore upstream changes needed for the project.
Consider setting merge.ff=false. This will make sure whenever you do a merge a corresponding merge commit is created. But remember now to always pull with the --rebase
option, otherwise each pull will create a merge commit, too. - A good alias is convenient.
I would recommend the following slightly adapted workflow:
first set up you config:
git config --global push.default current
git config --global merge.ff false
git config --global alias.up 'pull --rebase'
create your local branch
git checkout dvl_bkend
git branch -vv # dvl_bkend should track something like "origin/dvl_bkend"
git branch -m dvl_bogdan # creating your own branch by renaming the other is an easy way of tracking the original upstream
Work on the code. Commit frequently whenever you have finished some task. You can only roll back to states you committed. Once in a while do git up
to integrate upstream changes and notice conflicting changes.
Once you are finished with your work and think about making it available to others:
git rebase -i # have a look on your commits. You can reorder them, squash them together, correct errors in commit messages, etc.
git log -p -w --reverse @{u}.. # a final look at all the changes you are about to push
git push --set-upstream # push your changes to your own remote branch and change the upstream to track your own branch from now on.
once you have pushed you final commits, you want to merge the branch back:
git merge origin/dvl_bkend # optional, to notice potential merge conflicts
git checkout dvl_bkend
git merge --no-ff origin/dvl_bogdan
git push
Upvotes: 1