1

I don't know if rebase or merge strategies or anything here is what I need or want.

The scenario

dev---*
       \A------*------
                \A2---------

ultimatly, I could just merge A2 into dev. This is the end result, but, is there a way to merge A2 back into A and basically replace or overwrite all the commits post A2 branch?

Why? As a teaching moment. I would really like to be able to show the diff between the "head" of A vs A2 via viewing the merge or A2 into A (all merges are done as --no-ff)

clarification: it would be nice to see my git history like this

dev---*                        /---
       \A------*------       -*
                \A2---------/

so, the "merge" commit on A when viewed in something like gitlab will show me the diff.

I am just being picky about how the GitLab repository "graph" will look, as well as the individual commit view. The changes.

Maybe I'll just do some experimenting with merging.

more clarification new question. considering this git history

dev---*
       \A------*++++++
                \A2---------

Can I merge A2 into A completely overwriting all the + commits, but keep them in the history?

Chad
  • 1,139
  • 17
  • 41

3 Answers3

1

As @ChrisMaes pointed out in the comment, you can compare the total amount of changes that happened between the A and A2 branches by simply running git diff between their heads.

For example:

git diff A A2

will give you the changes that A2 were made in the A2 branch compared with A, while:

git diff A2 A

will give you the opposite, that is the changes that were made in A as compared to A2.

The reason you can do this is because in Git each commit points to a snapshot of all the files in your project as they were at the time of the commit.

From the "Snapshots, Not Differences" section of the documentation:

Git thinks of its data more like a set of snapshots of a mini filesystem. Every time you commit, or save the state of your project in Git, it basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot.

This means that the snapshot referenced by the latest commit of a branch (aka. the tip) contains the cumulative set of changes that happened in that branch―not just the differences between that commit and the previous one.

Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
  • In the end, I used git diff to preview what the merge would look like. I then just merged `A2` into `A` and spent some time "cleaning up". Every file with a merge conflict was just checkout out directly into `A` – Chad Aug 13 '19 at 14:03
1

If the only reason for doing this merge is to be able to view the difference explained in the last paragraph, I would suggest this:

git diff $(git merge-base A A2) A2

This will list all the diffs between the last mutual commit of A and A2 and the tip of the branch A2.

Edit: I've just learned that git diff A...A2 is syntactic sugar for git diff $(git merge-base A A2) A2, ie. it gives all the changes introduced in branch A2 since it diverged from A.

mimikrija
  • 113
  • 7
0

First, find the commit where A2 branched from A:

git merge-base A A2

This will give you the commit id. Then, if you don't mind losing your extra commits on A, reset A to that commit:

git checkout A
git reset --hard <commit id>

Then merge A2 into A:

git checkout A
git merge A2

Then merge A into dev:

git checkout dev
git merge A


Note: Instead of performing a hard reset on A, you could do git stash or save the diff to a patchfile:

git diff <commit id> > patchfile.diff
Irfan434
  • 1,463
  • 14
  • 19