git stable branch: find not cherry-picked commits
Asked Answered
T

2

22

I have the following git history:

A --- B --- C --- D' --- E' [master]
 \
  \ --- D --- E --- F [stable]

We have a policy to cherry-pick all changes from stable to master; D' and E' are cherry-picked commits from stable branch, F is not cherry-picked (has been forgotten).

How can I get a diff that bings up F (which was not cherry-picked into master)?


We don't want use merge because:

  • cleaner history without merge commits
  • commits to stable are rare
  • we have lots of different stable branches
Tocology answered 15/2, 2012 at 7:59 Comment(0)
W
18

That's exactly what the git cherry command is for.

It should never miss unpicked change, but it might occasionally list a change you consider picked if the pick involved conflict resolution.

Wares answered 15/2, 2012 at 9:40 Comment(2)
I wish it had option --no-merges that git log has.Braiding
@anjdreas It seems cherry does not list merge commits, with git 2.13.2.Tableware
K
-2

Git command cannot resolve this. I have written this script, it can help.

Script 1st calculates merge base of both branches branch1 and branch2. Then it makes two lists from merge base to head of branch1 and branch2 respectively. Then it creates a hash table of commits on branch2 with commit message's md5sum. Then it go through commit list of branch1 and check if that exist in branch2 hashtable or not?

In above case branch1 is stable and branch2 is master

#!/bin/bash

## Usage: ./missing_cherrypicks.sh branch1 branch2
## This script will find commits in branch1 missing in branch2
## Final list of missing commit will be in file missing_commits_branch1_branch2.csv

branch1=$1
branch2=$2

# Calculate mergebase of branch1 and branch2
mb=`git merge-base origin/$1 origin/$2`
rm -rf missing_commits_${branch1}_${branch2}.csv
echo "COMMIT,AUTHOR,MESSAGE,FILESLIST" >> missing_commits_${branch1}_${branch2}.csv

# Get commit list on both branches from merge-base
declare -a commitlist1=`git rev-list $mb..origin/$1`
declare -a commitlist2=`git rev-list $mb..origin/$2`

## Make HashKey for branch2
declare -A CommitHash
for com2 in ${commitlist2[@]}
do
  message2=`git log --pretty=oneline $com2 | head -1| sed "s/${com2} //" | sed 's/ *$//' | cut -c1-35`
  hashkey=`echo $message2 |md5sum |xargs | awk '{print $1}'`
  CommitHash[${hashkey}]=$com2
done

# Find commits of commitlist1 and check if they are in commitlist2
for com1 in ${commitlist1[@]}
do
   message1=`git log --pretty=oneline $com1 | head -1| sed "s/${com1} //"| sed 's/ *$//'| cut -c1-35`
   hashkey1=`echo $message1 |md5sum |xargs | awk '{print $1}'`
   if [[ -z ${CommitHash[${hashkey1}]} ]]
   then
      echo "------$com1-----------"
      author=$(git show $com1 |grep ^Author:|awk -F":" '{print $2}')
      fileslist=`git diff-tree --no-commit-id --name-only -r $com1`
      fl=""
      for file in ${fileslist[@]}
      do
          fl=${fl}":"$file
      done

      echo "------$author-------"
      echo "$com1,$author,$message1,$fl" >> missing_commits_${branch1}_${branch2}.csv
   fi
done
Knuckleduster answered 17/10, 2017 at 5:3 Comment(5)
Could you please elaborate how and why this solves the OPs issue? Just pasting some code is not a good answer, while it may technically answer the question.Magdalenamagdalene
Script 1st calculates merge base of both branches branch1 and branch2. Then it makes two lists from merge base to head of branch1 and branch2 respectively. Then it creates a hash table of commits on branch2 with message's md5sum. Then it go through commit list of branch1 and check if that exist in branch2 hash table or not.Knuckleduster
In above case, branch1 is stable and branch2 is master.Knuckleduster
Please edit your answer accordingly and don't add details as comments.Magdalenamagdalene
Added details with script.Knuckleduster

© 2022 - 2024 — McMap. All rights reserved.