Aşağıdaki geçmişi düşünün:
c---e---g--- feature
/ \
-a---b---d---f---h--- master
"C" komutu master ile birleştirildiğinde nasıl bulabilirim (örneğin, birleştirme komutu "h")?
Aşağıdaki geçmişi düşünün:
c---e---g--- feature
/ \
-a---b---d---f---h--- master
"C" komutu master ile birleştirildiğinde nasıl bulabilirim (örneğin, birleştirme komutu "h")?
Yanıtlar:
Örneğiniz şubenin featurehala kullanılabilir olduğunu göstermektedir .
Bu durumda haşağıdakilerin son sonucu:
git log master ^feature --ancestry-path
Şube featureartık mevcut değilse, birleştirme işlemlerini geçmiş satırında cve arasında gösterebilirsiniz master:
git log <SHA-1_for_c>..master --ancestry-path --merges
Bu ancak aynı zamanda sonra oldu tüm birleştirmeleri gösterecektir hve aralarında eve güzerinde feature.
Aşağıdaki komutların sonucunun karşılaştırılması:
git rev-list <SHA-1_for_c>..master --ancestry-path
git rev-list <SHA-1_for_c>..master --first-parent
size hortak son satır olarak SHA-1'i verecektir .
Elinizde varsa comm -1 -2, bu sonuçlarda kullanabilirsiniz . Msysgit kullanıyorsanız, karşılaştırmak için aşağıdaki perl kodunu kullanabilirsiniz:
perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' file1 file2
( http://www.cyberciti.biz/faq/command-to-display-lines-common-in-files/ adresinden "comp.unix.shell haber grubundaki birinden" alan perl kodu ).
Tek astar yapmak istiyorsanız işlem ikamesine bakın .
masterile birleştirildi feature, daha sonra hemen featurebirleştirilir masterhızlı ileri alma (ucu gibi featureyerine geçer master). --first-parentYanlış ebeveynin geri dönmesine neden olur mu?
comm -1 -2ama işe yaramadı. commyalnızca sıralı satırlarda çalışır. (Perl tek astar çalışır, ben okuyamıyordum.)
git find-merge h master(hiçbir şey döndürmez ancak h döndürmelidir), git find-merge d master(f döndürür ancak d döndürmelidir), git find-merge c feature(e döndürür ancak g döndürmelidir).
Bunu şu adrese ekleyin ~/.gitconfig:
[alias]
find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"
Sonra diğer adları şöyle kullanabilirsiniz:
# current branch
git find-merge <SHA-1>
# specify master
git find-merge <SHA-1> master
Birleştirme işleminin iletisini ve diğer ayrıntılarını görmek için git show-mergeaynı argümanlarla kullanın .
( Gauthier'in cevabına göre . Rosen Matev ve javabrett'e bir sorunu düzelttiği için teşekkür ederiz sort.)
sort -k2 | uniq -f1 -d | sort -n | tail -1 | cut -f2Ortak son satırı doğru bulmadığına dikkat edin . İşte başarısız olduğu bir örnek.
16db9fef5c581ab0c56137d04ef08ef1bf82b0b7Yapıştırınızda çalıştırdığımda burada bulur , bu beklenmiyor mu? Hangi işletim sistemindesiniz?
29c40c3a3b33196d4e79793bd8e503a03753bad1
git-get-merge , aradığınız birleştirme taahhüdünü bulur ve gösterir:
pip install git-get-merge
git get-merge <SHA-1>
Komutu bir birleştirme kadar verilen çocukları işlemek aşağıdaki içine başka dalı (muhtemelen usta) bulunur.
Yani, Gauthier'in gönderisini özetlemek gerekirse:
perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' <(git rev-list --ancestry-path <SHA-1_for_c>..master) <(git rev-list --first-parent <SHA-1_for_c>..master) | tail -n 1
EDIT: Bu işlem yerine " <()" kullandığından POSIX uyumlu değildir ve kabuğunuzla çalışmayabilir. İle bashya da zsholsa çalışır .
<()POSIX uyumlu değil. Sen kullanmak gerekir bash, zshya da bir kabuk destekleyen süreç ikame . Cevabımı buna göre düzenledim.
Bunu yapmam gerekiyordu ve bir şekilde buldum git-when-merged(ki bu gerçekten SO sorusuna atıfta bulunuyor, ancak Michael Haggerty burada çok güzel Python betiğine bir referans eklemedi). Şimdi yaptım.
Gauthier'in harika cevabına dayanarak comm, listeleri karşılaştırmak için kullanmamız gerekmez . Biz son sonuca arıyorsanız bu yana --ancestry-pathda olduğu --first-parent, biz sadece eski çıkışında ikincisi için yazılması edebilirsiniz:
git rev-list <SHA>..master --ancestry-path | grep -f <(git rev-list <SHA>..master --first-parent) | tail -1
Veya çabuk ve yeniden kullanılabilir bir şey için, işte burada bir fonksiyon .bashrc:
function git-find-merge() {
git rev-list $1..master --ancestry-path | grep -f <(git rev-list $1..master --first-parent) | tail -1
}
commgirişler sıralanmadığında çalışmadı.
Ruby kalabalığı için git-whence var . Çok kolay.
$ gem install git-whence
$ git whence 1234567
234557 Merge pull request #203 from branch/pathway
Yolda yerleştirdiğim bash betiğinin altında kullanıyorum ~/bin/git-find-merge. Bu dayanıyor Gauthier'in cevap ve evilstreak cevabı köşe davalarına bakacak birkaç tweaks. commgirişler sıralanmadığında atar. grep -fMükemmel çalışıyor.
Köşe dolapları:
~/bin/git-find-merge senaryo:
#!/bin/bash
commit=$1
if [ -z $commit ]; then
echo 1>&2 "fatal: commit is required"
exit 1
fi
commit=$(git rev-parse $commit)
branch=${2-@}
# if branch points to commit (both are same), then return commit
if [ $commit == $(git rev-parse $branch) ]; then
git log -1 $commit
exit
fi
# if commit is a merge commit on first-parent path of branch,
# then return commit
# if commit is a NON-merge commit on first-parent path of branch,
# then return branch as it's either a ff merge or commit is only on branch
# and there is not a good way to figure out the right commit
if [[ $(git log --first-parent --pretty='%P' $commit..$branch | \
cut -d' ' -f1 | \
grep $commit | wc -l) -eq 1 ]]; then
if [ $(git show -s --format="%P" $commit | wc -w) -gt 1 ]; then
# if commit is a merge commit
git log -1 $commit
else
# if commit is a NON-merge commit
echo 1>&2 ""
echo 1>&2 "error: returning the branch commit (ff merge or commit only on branch)"
echo 1>&2 ""
git log -1 $branch
fi
exit
fi
# 1st common commit from bottom of first-parent and ancestry-path
merge=$(grep -f \
<(git rev-list --first-parent $commit..$branch) \
<(git rev-list --ancestry-path $commit..$branch) \
| tail -1)
if [ ! -z $merge ]; then
git log -1 $merge
exit
fi
# merge commit not found
echo 1>&2 "fatal: no merge commit found"
exit 1
Bunu yapmama izin veren:
(master)
$ git find-merge <commit> # to find when commit merged to current branch
$ git find-merge <branch> # to find when branch merged to current branch
$ git find-merge <commit> pu # to find when commit merged to pu branch
Bu komut dosyası github'ımda da mevcut .
@ Robinst'in fikrinin yakut versiyonum, iki kez daha hızlı çalışır (çok eski bir taahhüt ararken önemlidir).
find-commit.rb
commit = ARGV[0]
master = ARGV[1] || 'origin/master'
unless commit
puts "Usage: find-commit.rb commit [master-branch]"
puts "Will show commit that merged <commit> into <master-branch>"
exit 1
end
parents = `git rev-list #{commit}..#{master} --reverse --first-parent --merges`.split("\n")
ancestry = `git rev-list #{commit}..#{master} --reverse --ancestry-path --merges`.split("\n")
merge = (parents & ancestry)[0]
if merge
system "git show #{merge}"
else
puts "#{master} doesn't include #{commit}"
exit 2
end
Sadece şu şekilde kullanabilirsiniz:
ruby find-commit.rb SHA master
Böyle bir şey deneyebilirsiniz. Fikir tüm birleştirme işlemlerini yinelemek ve "c" işlemine bunlardan birinden erişilip erişilemeyeceğini görmek:
$ git log --merges --format='%h' master | while read mergecommit; do
if git log --format='%h' $mergecommit|grep -q $c; then
echo $mergecommit;
break
fi
done
git rev-list <SHA-1_for_c>..master --ancestry-path --merges
Bunu birkaç kez yapmak zorunda kaldım (bu soruyu cevaplayan herkese teşekkürler!) Burada bulabilirsiniz: https://github.com/mwoehlke/git-utils/blob/master/bin/git-merge-point .