问题
I am new in git
and I am find it hard to wrap my head around the fact that everything is around snapshots/commits and not individual files.
So assume that I have a tree in my repository as follows.
C4 (HEAD,Master,Origin/Master)
*
C3
*
C2
*
C1
Now I branch out from here:
B1 (HEAD, testBranch)
*
C4 (HEAD,Master,Origin/Master)
*
C3
*
C2
*
C1
In my testBranch
I only modify 2 files of the whole repository. Just 2.
The development in master
in the remote repository continues so eventually we have the following tree:
C8(Master,Origin/Master)
*
B3(testBranch) C7
* *
B2 C6
* *
B1 C5
*
C4
*
C3
*
C2
*
C1
Now I have finished working on the branch and want to merge to master. But the master has moved further ahead.
But the only difference between B3
the latest of testBranch
and C8
the latest of master
are the changes in the 2 files that I originally started to work on when I forked the branch. But additionally testBranch
is "lest behind" the master
branch since other modifications have occurred.
So what will happen if I merge testBranch
to master
?
Will git
figure out that the only changes to merge are the 2 files I originally worked on?
Will I get conflicts? Should I not do a merge but a rebase? Why?
回答1:
I am find it hard to wrap my head around the fact that everything is around snapshots/commits and not individual files.
Did you used ClearCase before?
If yes, see this question for a difference between a file-centric VCS (here a CVCS) and a DVCS like git (that I introduce here).
So what will happen if I merge
testBranch
tomaster
? Will git figure out that the only changes to merge are the 2 files I originally worked on?
yes
But how does git "understand" that the different code in the branch has been made obsolete by the code in master? Due to timestamps?
Due to the fact that each commit knows its parent: that allows to find a common ancestor commit between B3
(merged to) C8
: C4
.
The merge operation know what has evolved since C4
: only 2 files, and it will merge only those to master
.
See also "What makes merging in DVCS easy?".
The merge operation know what has evolved since
C4
: only 2 files, and it will merge only those tomaster
.But
B1-C5
B2-C6
are different.
E.g. a function inC5
that exists inB1
andB2
could have been deleted.
I am not sure I understand how does it figure this out and it doesn't "reinclude" the function
It does figure out and not reintroduce that function because:
- that function existed in
C4
(common ancestor) - that function existed in
B2
(so no change there on the source branch of the merge) - that function no longer exist in
master
(but it is a change, a deletion here, which affects the destination branch of the merge)
A merge is about reporting and merging modifications from the source branch to the destination branch.
You are referring to a modification in the destination branch only, while the source branch has not evolved compared to the common ancestor:
- that function from
testBranch
will be ignored by the merge since there no modification to report. - that deleted function in
master
will be kept deleted by the merge, since the merge ignores said function fromtestBranch
(for the reason I just mentioned in the previous point: no modification since the common ancestor)
Will I get conflicts?
You could get a conflict if those two files have also changed in master (and if those changes occurred on common lines)
Should I not do a merge but a rebase? Why?
A rebase would be better if you didn't pushed yes testBranch
, and have other commits to do on it (but want to do them based on a up-to-date version of master
)
来源:https://stackoverflow.com/questions/17155436/can-git-figure-out-that-the-branch-to-be-merged-has-obsolete-changes