Ответ 1
Именно это означает git cherry
.
Он никогда не должен пропускать неопубликованные изменения, но иногда он может отображать изменение, которое вы считаете выбранным, если выбор подразумевает разрешение конфликтов.
У меня есть следующая история git:
A --- B --- C --- D' --- E' [master]
\
\ --- D --- E --- F [stable]
У нас есть политика для вишни - выбрать все изменения от стабильного до мастера; D 'и E' - это завитые вишнями коммиты из устойчивой ветки, F не выбрасывает вишню (был забыт).
Как я могу получить diff, который разбивает F (который не был выбран вишневым цветом в мастер)?
Мы не хотим использовать слияние, потому что:
Именно это означает git cherry
.
Он никогда не должен пропускать неопубликованные изменения, но иногда он может отображать изменение, которое вы считаете выбранным, если выбор подразумевает разрешение конфликтов.
Git не может решить эту проблему. Я написал это script, это может помочь.
Script 1st вычисляет базу слияния обеих ветвей branch1 и branch2. Затем он создает два списка из базы слияния в голову ветки 1 и ветки2 соответственно. Затем он создает хеш-таблицу коммитов на ветке2 с сообщением commit md5sum. Затем он переходит через список фиксации ветки1 и проверяет, существуют ли они в hashtable branch2 или нет?
В приведенном выше случае ветвь 1 устойчива, а branch2 - 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