Reputation: 1866
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
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