lilHar
lilHar

Reputation: 1866

Review changes that one branch overall added to another branch

I have branch (Trunk) and another branch (Feature1).

Feature1 was branched off of Trunk and later Trunk was updated by several other features branches. During which, to keep it up to date, Feature1 had Trunk merged in several times.

Eventually, Feature1 was merged into Trunk. After testing, there were pass backs with update requests, and Feature1 had Trunk merged in again, and had multiple commits, and then merged into Trunk again. This repeated a few times.

So now, git diff Trunk Feature1 just shows two identical branches

There are multiple commits that Feature1 has, so I don't have a clear visibility into a particular hash to target in either case. In which case, any given commit wouldn't have all the differences as there would be either missing commits or develop would already have a lot of the changes.

However, I'm wanting to repeat all the work done on Feature1 in a very similar project. The question at this point is "what all unique work happened on feature1?"

I would like to see what a diff would look like if feature1 had never been merged into develop, and I did the git diff trunk feature1 command. How would I do this?

So basically I need something like:

git diff Trunk --without="Feature1" Feature1

Upvotes: 0

Views: 54

Answers (1)

jthill
jthill

Reputation: 60295

First cut, going on your description: you want all the commits in Feature1's first-parent history that aren't in Trunk's first-parent history. Git's a tool in your toolkit, you also have a batch of text-processing tools, awk's what you want here:

( git rev-list --first-parent Trunk; echo; git rev-list --first-parent Feature1 ) \
| awk ' /^$/ { doneloading=1; next }
        !doneloading { Trunk[$1]=1 }
        doneloading && $1 not in Trunk
'

You can eyeball the commits that gets you by feeding the output through

git log --no-walk --stdin --oneline --decorate

You'll probably want to look at the merges from Trunk, to see whether any of them introduced changes of their own, you could add --parents to the Trunk rev-list to make those stand out.

How messy this job's going to be depends entirely on how messy the mergebacks from Trunk got. If there weren't any conflicts, if all the other changes on Trunk while Feature1 was being developed were incorporated clean, then you can just lose all those merges and batch-cherrypick or interactive-rebase the remaining ones onto an extract branch you just made up for this task. And then you can diff the extract tip against whatever base you picked for it to see what all the changes are, and you'll have a clean branch to rebase onto your customer's code -- you might consider reworking with an add --patch / commit series, there are few histories that couldn't stand a cleanup edit when you get the chance.

If you had side branches that also got merged into Feature1 this gets more complicated, you should find the newest commit that's in both Feature1's and Trunk's first-parent histories, that's the original branch point and the truncate your second rev-list there:

origbase=$( ( git rev-list --first parent Trunk
              git rev-list --first-parent Feature1
            ) | awk 'seen[$1]++ {print;exit}'
)

and then the first batch with --first-parent replaced by --not $origbase in the Feature1 rev-list. Again, you only need this check if the Feature1 history is a really glorious mess.

Upvotes: 1

Related Questions