I've been reading an article over here: 
She states the following problem:
What if X approved task 2 and merged it first then review task1 and merged it after? Remember that task 1 has no additional codes that task 2 has since it was the preceding task. To make more sense, think of it with task 2 as the Register functionality and task 1 as the basic setup. Basic setup branch won’t have the Register files since I didn’t write that functionality on task 1. If this task 1 branch is to be merged after task 2, wouldn’t it cancell out (delete) the register folder/file that got merged by task 2 from the first merge? How can we prevent this?
This is the sentence that boggles my mind:
"If this task 1 branch is to be merged after task 2, wouldn’t it cancell out (delete) the register folder/file that got merged by task 2 from the first merge?"
AFAIK, if task2 is merged to master, it'll take that entire path that connects it uptil master and merges all that to master.
task1 would only have 2 commits that aren't merged with master (consider those slashes to be commit ids). If we merge task1 afterward, it shouldn't have any problems whatsoever.
Or, if task#1 didn't have any extra commits then merging task#1 wouldn't lead to any problems, isn't it?
It's not like commits will be "canceled out" or "deleted" if we merge task1. Correct?
CodePudding user response:
Let's address your questions individually.
AFAIK, if
task2is merged tomaster, it'll take that entire path that connects it untilmasterand merge all that tomaster.
Correct. The resulting history would look like this:
o---o--------------M (master)
\ /
o---o---o---o (task2)
\
o---o (task1)
task1would only have 2 commits that aren't merged withmaster. If we mergetask1afterwards, it shouldn't have any problems whatsoever.
Also correct. There might be some merge conflicts depending on what changed in task1, but nothing out of the ordinary. The resulting history would look like this:
o---o--------------M---N (master)
\ / /
o---o---o---o / (task2)
\ /
o---o (task1)
Or, if
task1didn't have any extra commits then mergingtask1wouldn't lead to any problems, wouldn't it?
Nope. Git would literally tell you Already up-to-date. and call it quits.
It's not like commits will be "canceled out" or "deleted" if we merge
task1. Correct?
You're correct, commits are never deleted by a merge. Files, however, might. It depends on whether they were actively removed from the index by one of the commits that are being merged.
See, the fundamental problem with the statement you quoted from the article is this:
If this
task1branch is to be merged aftertask2, wouldn’t it cancel out (delete) the register folder/file that got merged bytask2from the first merge? How can we prevent this?
When you do a merge, Git combines the trees associated with the commits you're merging compared to their first common ancestor (known as the merge base). If a file that existed in the common ancestor was deleted in one of the commits on one side of the merge, then yes, that file would be deleted in the resulting merge.
To go back to our example:
o---o--------------M-----N (master)
\ / /
o---o---o---o / (task2)
^ \ /
foo.txt o---o (task1)
^
deletes foo.txt
If foo.txt existed in the common parent between task2 and task1, and task1 deleted it, then foo.txt would be removed in the merge commit N. It's worth noting that if task2 modified foo.txt after task1's fork point, then you would get a merge conflict.
Now, if task2 created foo.txt, merging task1 wouldn't delete it in master simply because foo.txt doesn't exist in task1:
o---o--------------M--------N (master)
\ / /
o---o---o---o / (task2)
\ ^ /
\ creates foo.txt
\ /
o---o (task1)
In this case, foo.txt would exist in the merge commit N.
If you're curious to see what the resulting tree would be like if you merged two branches, you can use the merge-tree command. For example:
git merge-tree $(git merge-base master task2) master task2
This would print out the paths of the files included in the tree that results from merging master and task2.
