sgroh
sgroh

Reputation: 354

GIT how to create patch from non consecutive commits

I have several commits in a branch "feature-1" that are part of some feature (lets call it feature X). In the branch exists also several merges from master, that means that feature X could be spread between other commits.

Also imagine that rebase was not used, so we can have something like:

 J - K - L - M - N                    [master]
  \             /(1)
   - A - B - C - D - E                [Branch feature-1]

The graphic above means that:

Graphically we have:

 J -  K - L - M - N                              [master]
  \            
   - A - B - C - K - L - M - N - D - E           [Branch feature-1]

Could we obtain commits A,B,C,D,E from feature-1 into a patch file?

UPDATE: There is another big restriction, changes A,B,C,D,E were merged also in master after commit E, so format-patch could not detect what is present on feature-1 that is not on master.

Upvotes: 3

Views: 712

Answers (2)

sgroh
sgroh

Reputation: 354

Finally the only way that I found is using a bash script. This could be avoided if GIT was used properly, I mean if merges only were applied on master (in this case Andrew's solutions works).

Another good solution was to rebase instead of merge, anyway, this is neither the main topic or my actual scenario, so the only workaround that I found to obtain a patch file was doing:

#!/bin/bash
if [[ $# -lt 1 ]]; then
  echo "Ilegal number of parameters."
  echo "Usage $0 PartialCommitMessage [file.patch]."
  exit 1;
fi
if [[ $# -eq 1 ]]; then
  FILE_NAME=$1.patch
else
  FILE_NAME=$2
fi
#First line needed in patch files.
echo "From: [email protected]" > $FILE_NAME
for rev in `git log --reverse --pretty=format:%H --grep=$1`
do
   cmd="git diff $rev^ $rev >> $FILE_NAME"
   echo $cmd
   eval $cmd
done

To find commits that contains some Ticket number(i.e: 1122) just run:

Usage:

./createPatch.sh 1122

Output:

A file called 1122.patch containing the diff changes.

Upvotes: 1

Andrew C
Andrew C

Reputation: 14823

Format-patch takes the same revision specifiers as most other git commands.

This should generate patches for only those commits reachable on feature-1 but not master.

git format-patch master..feature-1 

Updates

Presuming master in pointing at the merge commit you could try

git format-patch master^1..feature-1

Otherwise you could hardcode the SHA for the merge commit in place of master in the above.

If your history is worse than that then you might need to look at something like

untested

for rev in ${git rev-list --first-parent feature-1 ^ROOT_SHA
do
   git format-patch -1 ${rev} 
done

Upvotes: 0

Related Questions