Using git, how do I merge the main (upstream) branch into a topic branch but see the differences as if I merged the topic branch into the main branch?
It is our habit, when a topic branch is ready, to do the merge into the main branch (with git) as a two-stage process:
The advantage of this is that if there are any problems with the merged version, then they are likely to show up already in the topic branch where they don't bother the other developers yet.
The disadvantage is that when merging the main branch into the topic branch, then the reported differences are those introduced into the main branch by other developers. There can be very many of them, and I wasn't involved in making any of them, so it is difficult for me to verify that the merge did not make any mistakes.
If instead I immediately merge the topic branch into the main branch, without first merging the main branch into the topic branch, then the reported differences are only those introduced by me for the topic branch. Those are fewer in number, and I am intimately familiar with them, so it is a lot easier for me to verify that the merge did not make any mistakes, but then we don't get the advantage of first testing the combination in the context of the topic branch.
I cannot run the tests locally before pushing, so it is not an option to merge the topic branch into the main branch, then test, resolve any problems, and only then push the main branch.
Assuming that the merges go well, it doesn't matter for the final code whether I merge the topic branch into the main branch or the main branch into the topic branch: In both cases I end up with the same code, but associated with different branches.
What I would like is to have the merged code in the topic branch, but to see the differences as if I merged the topic branch into the main branch. What is the most convenient way to do that?
The clunky way is to have two local copies of the repository, with the main branch checked out in one of them and the topic branch checked out in the other one. Merge the topic branch into the main branch in the first repository copy (see only my own diffs -- excellent!), then copy the source code but not the .git directory to the other repository copy, and commit into the topic branch. This is cumbersome and wasteful of disk space.
I also tried merging the topic branch into the main branch (but not pushing!) and then doing a hard reset of the topic branch onto the merge commit in the main branch, but that merely moves the topic branch marker, losing the connection with the previous commits in the topic branch.
EDIT : I moved my own solutions from here to an Answer, 2019-11-29, at the suggestion of a comment.
FIRST PARTIAL SOLUTION, ADDED 2018-01-19
I've found a partial solution to my problem. When I'm in the middle of merging the main branch into the topic branch, then
git diff --stat MERGE_HEAD...
(note the three dots at the end) shows how many lines in which files have changed in the topic branch since the most recent common ancestor with the main branch. Those are the files that would be reported as changed if I instead merged the topic branch into the main branch; those are the files that I changed.
In my merge of the main branch into the topic branch, I can ignore all files that aren't in that list from git diff. Those files to be ignored weren't changed by me, so I do not need to double-check them for merge problems that git cannot detect.
SECOND PARTIAL SOLUTION, ADDED 2018-01-23
This solution is based on a comment that Steve added below this question, with some additions.
THIRD PARTIAL SOLUTION
And a colleague of mine suggested a third way to reduce the pain: Use a worktree to get a cheap second copy of the main branch without having to clone the entire repository again. Assuming that you're in the main repository directory "repo" with the topic branch checked out:
# create worktree and check out main-branch in it:
git worktree add ../repo-worktree main-branch
cd ../repo-worktree
git merge topic-branch
# (resolve any merge conflicts)
# copy changed files to the main repository:
cp <changed-files> ../repo
cd ../repo # go to main repository
git add -u # stage copied files (no new ones!)
git commit -m "merged main branch into topic branch"
# when you don't need the worktree anymore, then
rm -rf ../repo-worktree # removes worktree
git worktree prune # removes obsolete worktree administrative files
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.