For this
tutorial, dev1 and dev2 will use “git merge” to syncup
branches (local master with remote master, local branch with local master), and
since they just moved from SVN to Git, old habits die hard, they will keep
working on their local branch.
Day 1 end
This is the
end of day 1, dev1 is ready to
call a day, he is happy with this changes, and ready to push his changes to the
remote (we will assume dev1 is
almost the lucky one, and simplify his actions, in reality, everyone should take
similar actions as dev2) :
git checkout master
git merge t1
git push -v --tags --set-upstream origin
master:master
dev2 wants to do the same thing, he
first syncs up his local master with the remote master:
git checkout master
git pull origin master
Bad luck, dev2 finds out his branch t2 has deviated from master. He needs to get his changes
into master, so he merges t2
into master, and when he does
this, he runs into the dreaded conflict:
git checkout master
git merge t2
Git tries to
be smart, and performs an auto-merge, but it fails. Note, upon automerging
failure, Git has changed your file in the working directory, here is the
content of testf:
dev2 will need to manually resolve
this conflict (and delete those markers
<<<<<<< HEAD, =======, >>>>>>> t2),
he can signal to Git that the conflict has been resolved, and commit again (you
don’t need to do merge again, because you are still in the merge process):
git add testf
git commit
dev2 is happy and pushes his changes
to remote:
git push -v --tags --set-upstream origin
master:master
Day 2
dev1 and dev2 should have both deleted their local branch now that
all the changes have been pushed to the remote repository, and all the histories
are safely stored, but they choose to continue to use the local branches, and
that means they need to syncup their local branch with the remote master. Check
out the previous diagrams, t1
and t2 are behind the local
master which is in sync with the remote master.
dev1 syncs his local branch with the
remote master:
git checkout master
git pull origin master
git checkout t1
#!!!!here it doesn't conflict!
git merge master
And then he
commits 2 changes to t1,
echo 't1-c3' >> testf; git add testf;
git commit -m 't1-c3'
echo 't1-c4' >> testf1; git add testf1;
git commit -m 't1-c4'
And merges t1 into local master and pushes his
changes to the remote master:
git checkout master
git pull origin master
git merge t1
git push -v --tags --set-upstream origin master:master
In our
script, dev2 is always the
unlucky one. He doesn’t realize his local master is behind, and he continues to
work on his t2:
git checkout t2
echo 't2-c3' >> testf; git add testf; git commit -m 't2-c3'
Now he
realizes his local master is
behind, so he syncs up his local master
with the remote, and then anxious to make sure his changes are based on the
latest code, he merges master
into his local t2 and runs into
a confict:
git checkout master
git pull origin master
git checkout t2
git merge master
Running git status
shows you:
So again dev2 needs to carefully resolve the
conflict (be sure to check out each marked lines). He then commits again:
git add testf
git commit
dev2 thinks his work is not finished
and is not ready to push to remote master,
so he keeps working on t2:
echo 't2-c4' >> testf; git add testf; git commit -m 't2-c4'
Day 3
The sun
always smiles on dev1, and he
commits 1 change to t1 and
pushes to the remote master:
echo 't1-c5'>> testf; git add testf;
git commit -m 't1-c5'
git checkout master
git pull origin master
git merge t1
git push -v --tags --set-upstream origin
master:master
Back to our
unlucky dev2, he is ready to
push his changes. First, he syncs his local master to remote, and then merges t2 into local master and runs into a conflict:
git checkout master
git pull origin master
git merge t2
Poor dev2, he needs to resolve the conflict
again.
git add testf
git commit
because he
has spent so much time on resolving the conflict, before he pushes his local master to remote, he syncs up his
local master with the remote just to be sure there are no changes made that
overlap his changes:
git checkout master
git pull origin master
git push -v --tags --set-upstream origin
master:master
Resulting
diagram looks like this:
Lessons
learned:
- There are multiple branches involved, you need to be careful which one you are working on (so it is more difficult for a developer to use with Git)
- Git does automerge, and when there are conflicts, Git updates your working directory files with markers (<<<<<<< HEAD, =======, >>>>>>>), be sure to check out them out and delete them. if you find these markers confusing, you can use external merge/diff tools, such as BeyondCompare.
- And it is true that it is much harder to use Git than SVN.
No comments:
Post a Comment