0

I was developing in a feature branch. At that moment I'd made some other changes which are already merged into develop branch through PR in github and I needed those changes in my feature branch. So I decided to merge develop branch into my feature branch. I'd deleted some code in a file and committed in the feature branch. After merging develop into the feature branch, I found that the change of deletion code in the commit of the file disappeared and the deleted part was added back due to the merge operation. I would like to ask: under what circumstances does this happen? Thanks!

UPDATED:

I use github to view the history. Here is the example: This is the history of agent.go at the commit 80d82ee in the feature branch OWL-1697. This is the whole history of this file in feature branch OWL-1697. After the merge operation, the change of 80d82ee for this file disappeared.

2
  • git merge never deletes any commits at all. Why do you believe it did—or more specifically, what are you using to view the commits in the repository? Whatever you are using to view them may be lying to you, in the interest of not showing you "boring" commits. As to the other half of the question, it's true that merging may delete code (or even entire files), depending on what you are merging and how you request the merge to be done. In any case, consider trying to provide a minimal reproducible example. Commented May 26, 2017 at 7:36
  • I use github to view the history. Here is the example: This is the history of agent.go at the commit 80d82ee in the feature branch OWL-1697. This is the whole history of this file in feature branch OWL-1697. After the merge operation, the change of 80d82ee for this file disappeared. Commented May 26, 2017 at 7:56

2 Answers 2

2

I would not recommend using GitHub to view commit and file history. (GitHub may have some nice and/or fancy way to view these, but as a very causal user of GitHub, I do not know of one. The command line tools have extensive flags, although you must be something of a Git expert to know which to use, and when.)

TL;DR summary of why the merge went wrong

After you work through the text below, pay particular attention to these last few lines of the git log output:

* | | | | | 80d82eef [OWL-1730][common][nqm-mng] Code refactoring * | | | | | 2438360a [OWL-1667][common][nqm-mng] From `hbs` to `nqm-mng` | |_|/ / / |/| | | | * | | | | b598349a Merge pull request #295 from masato25/OWL-1724 

In commit 2438360a, you added some lines, and then in commit 80d82eef, you took them out again.

However, you put the same added lines in via commit d04492d9:

| | * | d04492d9 [OWL-1667][common][nqm-mng] From `hbs` to `nqm-mng` 

a bit higher up. You did this on the same day as the added lines in 2438360a. You took the lines out, in 80d82eef, much later ... but in a different branch. In topological order, you took the change out almost immediately after you put it in ... while also leaving the change in a separate branch. You then brought those into another branch via e1d369d0, which you brought into another branch, and so on until you brought them right back into the branch you thought you had taken them out of.

Viewing the commit graph

If I clone your repository and use git log --all --decorate --oneline --graph to view it, I see this, in part, which includes commit 80d82eef (at the bottom):

* aeecad13 (origin/OWL-1697) [OWL-1730][nqm-mng] Update debug message * f0797f8e [OWL-1730][nqm-mng] Fix the proble from merge * 5aaba93b [OWL-1730][nqm-mng] Drop gin's "gopkg.in" paths [mass snip] * | | | d2d4debd [OWL-1730][nqm-mng] Tests * | | | e1037c28 [OWL-1730][nqm-mng] Queue service * | | | a847d783 Merge branch 'OWL-1677' into OWL-1697 |\ \ \ \ | * \ \ \ ea916618 Merge branch 'develop' into OWL-1677 | |\ \ \ \ | | |/ / / | * | | | 056a7442 [OWL-1677] Refactoring testing to usage of Ginkgo | * | | | 800c3f09 [OWL-1677] Add utilities for testing by Ginkgo framework | * | | | 85deb914 Merge branch 'develop' into OWL-1677 | |\ \ \ \ | * | | | | c830da0f [OWL-1677] Fix tests | * | | | | 14d8571c [OWL-1677] Refactoring test to Ginkgo | * | | | | 8538306f [OWL-1677] Re-write testing to Ginkgo framework * | | | | | 906741cd [OWL-1730][nqm-mng] Rename types and methods * | | | | | 80d82eef [OWL-1730][common][nqm-mng] Code refactoring 

We can see that the commit is in fact still there, not deleted by the merge.

Finding commits that affect a file: --full-history

Now, the file you care about here is named modules/nqm-mng/restful/agent.go in commit 80d82eef. As we can see from the --decorate otuput, a branch name that leads here is origin/OWL-1697. The commits that modify this particular file, however, are a bit tricky to find.

The first bit of magic to know is to use --full-history when restricting git log to path names (I suspect there is no way to get GitHub to do this). The reason is that if a merge has undone something you wanted done, Git's "history simplification", which removes commits that don't contribute to the final version of the source, makes it impossible to find out which merge removed that contribution.

The second bit of magic to know is that when looking at merge commits, we may want -m to make Git "split" the merge into the two halves.

I also use --topo-order to force Git to show commits in a topologically sensible order (usually not necessary, but generally a good idea here).

Who did what

We might take a look at precisely what 80d82eef does to the file of interest at this point:

$ git show 80d82eef -- modules/nqm-mng/restful/agent.go commit 80d82eef9606800c094858ac0d60f27ef9ad1307 Author: chyeh <[email protected]> Date: Fri May 19 11:34:09 2017 +0800 [OWL-1730][common][nqm-mng] Code refactoring Move some code from `common/` to `modules/nqm-mng/` as the preparation of the following development. diff --git a/modules/nqm-mng/restful/agent.go b/modules/nqm-mng/restful/agent.go index 3ba34901..f21afd05 100644 --- a/modules/nqm-mng/restful/agent.go +++ b/modules/nqm-mng/restful/agent.go @@ -124,10 +124,3 @@ func clearCachedTargetsOfAgentById( r := commonNqmDb.DeleteCachedTargetsOfAgentById(q.AgentID) return mvc.JsonOutputOrNotFound(r) } - -func nqmAgentHeartbeat( - req *commonNqmModel.AgentHeartbeatRequest, -) mvc.OutputBody { - r := commonNqmDb.AgentHeartbeat(req) - return mvc.JsonOutputBody(r) -} 

Now we can run this rather long command (I've broken it into two lines for display purposes):

$ git log --full-history -m -p --topo-order \ origin/OWL-1697 -- modules/nqm-mng/restful/agent.go 

Note the three extra options (full history, merge split, and topological order).

The output is long so I won't quote it all, but the commits displayed are:

  • f0797f8e1e2e5a41db30225f4e72dc987b055ac8, in which you re-delete the lines brought back by the failed merge;
  • 7e00e309f0ed5750f6b7b052e77431ec4797d601 (vs its first parent d2d4debd), which re-adds the lines you did not want);
  • 648a324e1333814968a09e4b0277fc0774b4fce6 (vs its first parent 447ac685), which affects just an import line;
  • ccbad82029c50040250a48180caeacfcc57044bd (vs its second parent da0dcde6), which also re-adds the lines you did not want;
  • dfa34ab98170d62e1bb6d624c2d09f9e4e7e0b57 (vs its second parent 5571dc2c);
  • 219347a6f1649ccfee8e69b481e3166d8d310fe0 (vs its second parent 1a60e4aa);
  • b11d41be75700c450280a4a5e0edb12381045303 (vs its second parent 28176808);
  • 8f5a0e242fd7c7ded6cdcc4517c33c793b96f8ea (vs its second parent 5178acdb);
  • e1d369d06a49846f39661642bdfb7c0c81a86b8e (vs its first parent 8b1d4f0f);
  • d04492d986fdf1257cb93a5524f2501e767bd564: this is an ordinary commit that you made on 2 May, in which you added the lines you do not want;
  • 80d82eef9606800c094858ac0d60f27ef9ad1307: this is the ordinary commit you made on 19 May, in which you deleted the lines you do not want;
  • 2438360a653e5c158b366f313bf771db4f294147: this is an ordinary commit that you made on 2 May, in which you added the lines you do not want;
  • and then numerous irrelevant commits that do not affect the lines you care about, all predating these changes.

Putting these in context

Depending on how you do your merges, the "most interesting" ones tend to be the first parent ones. This is the case above.

It's also a good idea to look at the merge base of the merge that brought back the changes you did not want. To do this, we need to run git merge-base on the two hash IDs of the two parents of that merge. As a reminder, that merge's hash ID is 7e00e309 (or 7e00e309f0ed5750f6b7b052e77431ec4797d601 in full). So let's run git merge-base on the two parents:

$ git merge-base --all 7e00e309^1 7e00e309^2 b598349a0ba6d6901ef812440746e2dc633c4cdc 

Commits "below" this point tend not to be of interest.

We can now use:

git log --decorate --oneline --graph origin/OWL-1697 

to view all of these in their complete context, although matching up the hash IDs is quite difficult and painful. Or, we can run:

git log --decorate --oneline --graph origin/OWL-1697 \ --full-history -- modules/nqm-mng/restful/agent.go 

to strip this display down to just commits that touch that file, when compared to any of their parent commits. The result is still quite long, but is now follow-able. Let's follow it down to the merge base, i.e., the commit starting with b598349a:

* f0797f8e [OWL-1730][nqm-mng] Fix the proble from merge * 7e00e309 Merge branch 'develop' into OWL-1697 |\ | * 648a324e Merge pull request #306 from Cepave/OWL-1771 | |\ | | * 4d722f8d [OWL-1771] Change `gin`'s import paths | * | 447ac685 Merge branch 'roby-testing' into develop | |\ \ | * | | ee1daba9 Merge pull request #305 from masato25/OWL-1674_ma | | |/ | |/| | * | ccbad820 Merge pull request #303 from masato25/OWL-1740 | |\ \ | * \ \ 69a9ee6e Merge pull request #302 from masato25/OWL-1765 | |\ \ \ | | * \ \ 9e9d1a55 Merge branch 'develop' into OWL-1765 | | |\ \ \ | | |/ / / | |/| / / | | |/ / | * | | dfa34ab9 Merge pull request #300 from masato25/OWL-1740 | |\ \ \ | | |/ / | * | | 219347a6 Merge pull request #301 from masato25/OWL-1755 | |\ \ \ | | |/ / | * | | b11d41be Merge pull request #299 from masato25/OWL-1755 | |\ \ \ | | |/ / | | | / | | |/ | |/| | * | 8f5a0e24 Merge pull request #298 from humorless/OWL-1644-c | |\ \ | * \ \ e1d369d0 Merge pull request #286 from Cepave/OWL-1667 | |\ \ \ | | |/ / | |/| | | | * | d04492d9 [OWL-1667][common][nqm-mng] From `hbs` to `nqm-mng` | * | | 8b1d4f0f Merge pull request #297 from hitripod/develop | |\ \ \ | * | | | 05e45dc8 Merge pull request #296 from masato25/OWL-1765 | | |_|/ | |/| | * | | | a847d783 Merge branch 'OWL-1677' into OWL-1697 |\ \ \ \ | * \ \ \ ea916618 Merge branch 'develop' into OWL-1677 | |\ \ \ \ | | |/ / / | |\ \ \ \ | | |/ / / | * | | | 85deb914 Merge branch 'develop' into OWL-1677 | |\ \ \ \ * | | | | | 80d82eef [OWL-1730][common][nqm-mng] Code refactoring * | | | | | 2438360a [OWL-1667][common][nqm-mng] From `hbs` to `nqm-mng` | |_|/ / / |/| | | | * | | | | b598349a Merge pull request #295 from masato25/OWL-1724 | |_|/ / [snip] 

This output contains all the reasons why your merge went wrong. As far as Git is concerned, adding and then immediately removing those lines, in commits 2438360a and 80d82eef, was quite irrelevant. What mattered was the independent and never-undone adding of those same lines in d04492d9. That's the source of the change brought in by a series of merges, and ultimately brought in by merge 7e00e309. All Git could tell is that those lines were supposed to be there, because they were added by one "side" of the merge, and the other side did nothing to the file!

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot! Based on your answer I figured out the reason. That was because I rebase'd OWL-1667, which caused an unnecessary commit 2438360a .
0

Since your file changes which you made in feature branch is not yet committed, while merging you probably stashed them. so while merge in operation those changes added back.

1 Comment

Sorry it was not clear in the description. Those changes in the feature branch was already committed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.