Git şubesinin en yakın üst öğesini nasıl bulabilirim?


419

Diyelim ki böyle bir taahhüt ağacına sahip aşağıdaki yerel depoya sahibim:

master --> a
            \
             \
      develop c --> d
               \
                \
         feature f --> g --> h

masterbenim olan bu son kararlı sürüm kodu olan , developolan benim bu 'gelecek' salma kodudur ve featureolduğu için hazırlanmakta olan yeni bir özellikdevelop .

Kanca kullanarak uzaktan repo'mda yapabilmek istediğim şey, featuretaahhüt HEAD'in fdoğrudan torunu olmadığı sürece itmelerin reddedilmesidir develop. özelliği olmuştur çünkü böyle ağaç görünüyor işlemek yani git rebaseüzerinde d.

master --> a
            \
             \
      develop c --> d
                     \
                      \
               feature f --> g --> h

Yani aşağıdakileri yapmak mümkün:

  • Şunun ana dalını tanımlayın feature?
  • fSoyundan gelen ana daldaki taahhüdü tanımlar ?

Oradan, ana dalın HEAD'inin ne olduğunu kontrol edeceğim fve özelliğin yeniden temellenmesi gerekip gerekmediğini belirlemek için, selefinin ana şube HEAD'iyle eşleşip eşleşmediğini göreceğim .


bir ebeveynin ebeveynini bulmak için bu sorunun yeniden yazılması gerekir.
Tim Boland

Yanıtlar:


347

Uzak deponun geliştirme dalının bir kopyasına sahip olduğu varsayılarak (ilk açıklamanız yerel bir depoda açıklanır, ancak uzaktan kumandada da varmış gibi görünür), istediğinizi, ancak yaklaşımı elde edebilmeniz gerekir. öngördüğünüzden biraz farklı.

Git'in geçmişi bir DAG taahhütüne dayanmaktadır . Şubeler (ve genel olarak "referanslar"), sürekli büyüyen taahhüt DAG'sindeki belirli taahhütlere işaret eden geçici etiketlerdir. Bu nedenle, dallar arasındaki ilişki zaman içinde değişebilir, ancak taahhütler arasındaki ilişki değişmez.

    ---o---1                foo
            \
             2---3---o      bar
                  \
                   4
                    \
                     5---6  baz

Görünüşe bazgöre (eski bir sürümü) bar? Peki ya silersek bar?

    ---o---1                foo
            \
             2---3
                  \
                   4
                    \
                     5---6  baz

Şimdi bazdayanıyor gibi görünüyor foo. Ancak, soyları bazdeğişmedi, sadece bir etiketi (ve ortaya çıkan sarkan taahhüdü) kaldırdık. Ya yeni bir etiket eklersek 4?

    ---o---1                foo
            \
             2---3
                  \
                   4        quux
                    \
                     5---6  baz

Şimdi bazdayanıyor gibi görünüyor quux. Yine de, soy değişmedi, sadece etiketler değişti.

Ancak, “taahhüt 6bir taahhüt torunu 3mu?” Diye sorsaydık. (varsayarak 3ve 6ister, o zaman cevabı “evet” olacağını SHA-1 adları işlemek dolu) barve quuxetiketlerin mevcut veya değildir.

Böylece, “itilen taahhüt geliştirme dalının mevcut ucunun bir inişi mi?” Gibi sorular sorabilirsiniz , ancak “itilen taahhüdün ana kolu nedir?” Diye soramazsınız.

İstediğiniz şeye yaklaşan çoğunlukla güvenilir bir soru:

Ebeveyn olarak mevcut geliştirme ipucuna sahip olan tüm itilmiş taahhüdün ataları (mevcut geliştirme ucu ve ataları hariç) için :

  • böyle bir taahhüt var mı?
  • tüm bu taahhütler tek ebeveynli taahhütler midir?

Hangi olarak uygulanabilir:

pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
    echo "'$basename' is missing, call for help!"
    exit 1
fi
parents_of_children_of_base="$(
  git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
  grep -F "$baserev"
)"
case ",$parents_of_children_of_base" in
    ,)     echo "must descend from tip of '$basename'"
           exit 1 ;;
    ,*\ *) echo "must not merge tip of '$basename' (rebase instead)"
           exit 1 ;;
    ,*)    exit 0 ;;
esac

Bu, kısıtlamak istediğiniz şeylerin bazılarını kapsayacaktır, ancak belki her şey olmayabilir.

Başvuru için, genişletilmiş bir örnek geçmişi aşağıda verilmiştir:

    A                                   master
     \
      \                    o-----J
       \                  /       \
        \                | o---K---L
         \               |/
          C--------------D              develop
           \             |\
            F---G---H    | F'--G'--H'
                    |    |\
                    |    | o---o---o---N
                     \   \      \       \
                      \   \      o---o---P
                       \   \   
                        R---S

Yukarıdaki kod reddetmek için kullanılabilir Hve Skabul ederken H', J, K, veya N, ama aynı zamanda kabul edeceğini Lve P(onlar birleştirmeleri dahil, ancak ucu birleştirmezseniz geliştirmek ).

Ayrıca reddetmek Lve Psoruyu değiştirmek ve

Tüm itilen taahhütlerin ataları için (mevcut geliştirme ipucu ve ataları hariç ):

  • iki ebeveyn ile herhangi bir taahhüt var mı?
  • değilse, böyle bir taahhüt en azından bir ebeveynini geliştirmek için mevcut ipucuna sahip mi?
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
    echo "'$basename' is missing, call for help!"
    exit 1
fi
parents_of_commits_beyond_base="$(
  git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
  grep -v '^commit '
)"
case "$parents_of_commits_beyond_base" in
    *\ *)          echo "must not push merge commits (rebase instead)"
                   exit 1 ;;
    *"$baserev"*)  exit 0 ;;
    *)             echo "must descend from tip of '$basename'"
                   exit 1 ;;
esac

Bunu alıyorum: git: fatal: belirsiz argüman '...': hem revizyon hem de dosya adı. üçlü nokta niyeti nedir?
Jack Ukleja

1
@Schneider Eminim ki '...' bu örnekte bir yer tutucu olarak tasarlanmıştır: eğer onu bu taahhüdün SHA'sı ile değiştirirseniz, bu kontrolü gerçekleştirmeye çalışıyorsunuz (diyelim ki şubenin KAFA) şu anda açıksınız), her şey iyi çalışıyor.
Daniel Brady

Bu ayrıntılı cevap için teşekkürler! Süper kullanışlı. Benzer bir kanca yapmak istiyorum, ancak geliştirme dalının adını sabit kodlamak istemiyorum. Üst şube dışında bir şubeye rebase önlemek için bir kanca istiyorum. Cevabınızı iyi anlarsam (bash ve diğer şeylerde yeniyim) bu cevabınızın kapsamında değil, değil mi? Bunu yapmanın bir yolu var mı?
Kemeia

İlgili bir soruyu cevaplamak istiyor musunuz? Kodunuzu UZAKTAN bir depoda çalışmak için alamadım. Yaklaşımınızı bir UZAKTAN depo ile çalışmak için nasıl uyarlayacağınızla ilgili aşağıdaki soruya bağlantı: stackoverflow.com/questions/49619492/…
CodeMed

Bu benim için işe yaramadı develop > release > feature, geri gelmek istiyorum ve ebeveyn bilmek gerekir.
Sorunumun

240

Bir rephrasal

Soruyu ifade etmenin bir başka yolu da "Şimdiki şube dışındaki bir dalda bulunan en yakın taahhüt nedir ve bu hangi branştır?"

Bir çözüm

Biraz komut satırı büyüsü ile bulabilirsiniz

git show-branch \
| sed "s/].*//" \
| grep "\*" \
| grep -v "$(git rev-parse --abbrev-ref HEAD)" \
| head -n1 \
| sed "s/^.*\[//" 

İle awk :

git show-branch -a \
| grep '\*' \
| grep -v `git rev-parse --abbrev-ref HEAD` \
| head -n1 \
| sed 's/[^\[]*//' \
| awk 'match($0, /\[[a-zA-Z0-9\/-]+\]/) { print substr( $0, RSTART+1, RLENGTH-2 )}'

Şöyle çalışır:

  1. Uzak dallar da dahil olmak üzere tüm taahhütlerin metin geçmişini görüntüleme.
  2. Mevcut taahhüdün ataları bir yıldızla gösterilir. Diğer her şeyi filtreleyin.
  3. Geçerli daldaki tüm taahhütleri yoksay.
  4. İlk sonuç en yakın ata dalı olacaktır. Diğer sonuçları yok sayın.
  5. Şube adları [parantez içinde] görüntülenir. Parantezlerin ve parantezlerin dışındaki her şeyi göz ardı edin.
  6. Bazen şube adı, başvurulan taahhüt ve şube ucu arasında kaç işlem bulunduğunu belirtmek için ~ # veya ^ # içerebilir. Umurumuzda değil. Boşver onları.

Ve Sonuç

Yukarıdaki kodun çalıştırılması

 A---B---D <-master
      \
       \
        C---E---I <-develop
             \
              \
               F---G---H <-topic

Verecek developsen H onu çalıştırırsanız ve mastersen I'den çalıştırırsanız,

Kod bir öz olarak kullanılabilir


24
Hataya neden olan bir arka engel kaldırıldı. Gerçi bu komutu çalıştırırken, diyordum her şube şikayet, uyarılar büyük miktarda almakcannot handle more than 25 refs
Jon L.

1
@JoeChrysler Eğer 2 bir satır yerine bunu yapmak ve muhtemelen gibi Mac üzerinde çalışmak yapabilir sizce ack(Biri değiştirilmesi önerdi Mac üzerinde mevcut değildir ackile grep)
nonopolarity

53
Üzgünüm, bu yanlış bir tane. İşte benim için doğru olanı:git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'
droidbot

15
@droidbot Güzel, ancak grep -v catch taahhüt mesajı veya şube adınız başka bir şube adının parçası olduğunda ref'lerin kaldırılmasını önlemek için boruların yeniden sıralanması gerekir. git show-branch | sed "s/].*//" | grep "\*" | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed "s/^.*\[//"
gaal

3
@OlegAbrazhaev Sorunuzun yanıtını alıp almadığınızı bilmiyorum. git takma adını kullanarak: parent = "!git show-branch | grep '*' | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//' #"works for me
mduttondev

111

Ayrıca deneyebilirsiniz:

git log --graph --decorate

5
git log --graph --decorate --simplify-by-decorationburada --graphisteğe bağlıdır.
Na13-c

1
git log --graph --decorate --simplify-by-decoration --oneline
anishtain4

106

git ebeveyn

Sadece komutu çalıştırabilirsiniz

git parent

@Joe Chrysler'ın cevabını git takma adı olarak eklerseniz, şubenin üst öğesini bulmak için . Kullanımı basitleştirecektir.

Konumundaki "~/.gitconfig"herhangi bir metin düzenleyicisini kullanarak bulunan gitconfig dosyasını açın . (Linux için). Ve Windows için ".gitconfig" yolu genelliklec:\users\your-user\.gitconfig

vim  ~/.gitconfig

Aşağıdaki alias komutunu dosyaya ekleyin:

[alias]
            parent = "!git show-branch | grep '*' | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//' #"

Kaydedip çıkın.

Komutu çalıştır git parent

Bu kadar!


5
Bu harika bir çözüm. Beklenen sonuçlardan emin olmak için bazı örnek çıktılar eklemek de yararlı olacaktır. Koştuğumda, ana şubenin adı olduğuna inandığım son satırdan önce birkaç uyarı aldım.
ttemple

4
Tıkır tıkır çalışıyor! Windows kullanıcıları için .gitconfig genellikle c: \ users \ your-user \ .gitconfig
zion

12
Alma cannot handle more than 25 refsistisna.
shajin

Birisi uyarıyı ele almak için bunu düzenleyebilir mi? @ttemple, yapabilir misin?
NIKHIL CM

@NIKHILCM bir Şampiyon gibi çalışır. Ama burada ebeveynin dalın nereden oluştuğunu veya başka bir şeyi belirtip belirtmediği konusunda bir sorum var?
Hariprasath

52

Genel sorununuza bir çözümüm var ( featureucundan alınıp developalınmadığını belirleyin), ancak özetlediğiniz yöntemi kullanarak çalışmaz.

Sen kullanabilirsiniz git branch --containsucundan soyundan tüm dalları listelemek için developdaha sonra kullanmak grepemin olmak için featurebunlardan biri.

git branch --contains develop | grep "^ *feature$"

Bunların arasındaysa, " feature"standart çıktıya yazdırır ve 0 dönüş koduna sahiptir. Aksi takdirde, hiçbir şey yazdırmaz ve 1 dönüş koduna sahiptir.


1
Bu işe yarıyor, ancak çok fazla referansa sahip bir depoda uzun sürebileceği unutulmamalıdır. Bu, örneğin bir ön alma kancasının içine girmek için idealden biraz daha az olmasını sağlar.
ebneter

Şube arıyordum, biz onu çağıracağım, yaptığım yer <branch>: git checkout -b <branch-2>from ... BU cevap! Gerçekten grep'e gerek yok. git branch --contains <branch>
Poopy McFartnoise

44

Bu benim için iyi çalışıyor.

git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'

Nezaket cevapları: @droidbot ve @Jistanidiot


Evet, ama bazen seni grep'ten "kırık boru" alır.
Vladislav Rastrusny

1
*grep'e geçmek için uygun bir normal ifade değildir. Kullanmalı grep -F '*'veya grep '\*'onun yerine. Aksi takdirde iyi bir çözüm.
arielf

Hiç çıktım yok.
Sandip Subedi

benim için çalışıyor ....
roottraveller

11

Yukarıdaki cevapların hiçbiri depomuzda işe yaramadığından, en son birleştirmeleri kullanarak kendi yolumu paylaşmak istiyorum git log:

#!/bin/bash
git log --oneline --merges "$@" | grep into | sed 's/.* into //g' | uniq --count | head -n 10

git-last-mergesBir dal adını argüman olarak (geçerli dal yerine) ve diğerlerini de kabul eden bir komut dosyasına koyungit log argümanları

Çıktıdan, ana dal (lar) ı kendi dallanma kurallarına ve her daldan birleştirme sayısına göre manuel olarak tespit edebiliriz.

DÜZENLEME: Eğer kullanırsanız git rebasegenellikle çocuk dallarında (ve birleştirmeleri yüzden çok fazla birleştirme kaydedilmesini bulunmamaktadır genellikle hızlı iletilir) Bir senaryo yazdı yüzden, bu yanıt öncesinde kaydedilmesini (normal ve birleştirme) saymak, iyi çalışmaz ve mevcut branşla karşılaştırıldığında tüm branşlarda taahhütlerin arkasında (ana dalda birleştirme işleminin arkasında olmamalıdır). Bu komut dosyasını çalıştırın ve sizin için işe yarayıp yaramadığını bana bildirin

#!/bin/bash
HEAD="`git rev-parse --abbrev-ref HEAD`"
echo "Comparing to $HEAD"
printf "%12s  %12s   %10s     %s\n" "Behind" "BehindMerge" "Ahead" "Branch"
git branch | grep -v '^*' | sed 's/^\* //g' | while read branch ; do
    ahead_merge_count=`git log --oneline --merges $branch ^$HEAD | wc -l`
    if [[ $ahead_merge_count != 0 ]] ; then
        continue
    fi
    ahead_count=`git log --oneline --no-merges $branch ^$HEAD | wc -l`
    behind_count=`git log --oneline --no-merges ^$branch $HEAD | wc -l`
    behind_merge_count=`git log --oneline --merges ^$branch $HEAD | wc -l`
    behind="-$behind_count"
    behind_merge="-M$behind_merge_count"
    ahead="+$ahead_count"
    printf "%12s  %12s   %10s     %s\n" "$behind" "$behind_merge" "$ahead" "$branch"
done | sort -n

Teşekkürler. Her ne kadar rebasesık kullanırsanız (ve birleştirmeler fast-forwardsık sık düzenlenirse) bu çok iyi çalışmayabilir . Daha iyi bir çözüm bulduğumda cevabımı düzenleyeceğim.
saeedgnu

1
Tek? şimdiye kadar cevap mevcut şube usta durumunda benim için mantıklı çalıştı. Diğer çözümlerin çoğu, gerçek ana dalların olmadığı bu kuşkusuz uç durumda rastgele (ve açıkça yanlış) bir sonuç verdi.
arielf

Benim için işe yarayan tek cevap bu. İlk 10'un listesi yerine ilk ebeveyni almak için bunu kullanabilirsiniz: git log --oneline --merges "$@" | grep into | sed 's/.* into //g' | uniq --count | head -n 1 | cut -d ' ' -f 8
lots0logs

10

Bir çözüm

Dayalıgit show-branch çözüm benim için pek işe yaramadı (aşağıya bakınız), bu yüzden ben dayalıgit log ve bu ile sonuçlandı:

git log --decorate --simplify-by-decoration --oneline \ # selects only commits with a branch or tag
      | grep -v "(HEAD" \                               # removes current head (and branch)
      | head -n1 \                                      # selects only the closest decoration
      | sed 's/.* (\(.*\)) .*/\1/' \                    # filters out everything but decorations
      | sed 's/\(.*\), .*/\1/' \                        # picks only the first decoration
      | sed 's/origin\///'                              # strips "origin/" from the decoration

Sınırlamalar ve Uyarılar

  • HEAD sökülebilir (birçok CI aracı, belirli bir dalda doğru taahhütte bulunmalarını sağlamak için bunu yapar), ancak başlangıç ​​dalı ve yerel dal hem eşit hem de "yukarıda" olmalıdır , mevcut KAFA'nın .
  • Etiket olmamalıdırYolda (sanırım; betiği alt ve üst şube arasında bir etiketle tamamlandığında test etmedim)
  • senaryo aslında dayanır "HEAD" hep olduğu ilk dekorasyon olarak listelenen tarafındanlog komuta
  • çalışan komut üzerine mastervedevelop sonuçlar (daha çok) içerisinde<SHA> Initial commit

Sonuçlar

 A---B---D---E---F <-origin/master, master
      \      \
       \      \
        \      G---H---I <- origin/hotfix, hotfix
         \
          \
           J---K---L <-origin/develop, develop
                \
                 \
                  M---N---O <-origin/feature/a, feature/a
                       \   \
                        \   \
                         \   P---Q---R <-origin/feature/b, feature/b
                          \
                           \
                            S---T---U <-origin/feature/c, feature/c

Yerel şube varlığına rağmen (örneğin origin/topic, taahhüt Odoğrudan SHA tarafından kontrol edildiğinden beri mevcuttur ), komut dosyası aşağıdaki gibi yazdırılmalıdır:

  • Kaydedilmesini için G, H,I (dal hotfix) →master
  • Kaydedilmesini için M, N,O (dal feature/a) →develop
  • Kaydedilmesini için S, T,U (dal feature/c) →develop
  • Kaydedilmesini için P, Q,R (dal feature/b) →feature/a
  • Kaydedilmesini için J, K, L(şube develop) → <sha> Initial commit*
  • Kaydedilmesini için B, D, E, F(dal master) →<sha> Initial commit

* - ya masterda developtaahhütleri ustanın HEAD'inin üstünde olsaydı (~ ustanın geliştirilmesi hızlı bir şekilde engellenebilirdi)


Şube benim için neden işe yaramadı

Solüsyon dayalıgit show-branch aşağıdaki durumlarda benim için güvenilmez olduğunu kanıtladı:

  • müstakil KAFA - müstakil kafa kasası dahil grep '\*' \`` grep '' yerine geçmesi anlamına gelir ! \ - ve bu tüm sorunların sadece başlangıcı
  • çalışan senaryoyu üzerinde mastervedevelop sonuçların developsırasıyla `` ve
  • üzerinde dallarmaster dalı ( hotfix/dallar) ile bitirmek developen yakın beri bir ebeveyn olarak masterşube veli ile kutlandı !yerine *bir sebebi var.

2
Sadece işe yarayan cevap - git takma adı olarak:"!git log --decorate --simplify-by-decoration --oneline | grep -v '(HEAD' | head -n1 | sed 's/.* (\\(.*\\)) .*/\\1/' | sed 's/\\(.*\\), .*/\\1/' | sed 's/origin\\///'"
Ian Kemp

8

"Git: Bir taahhüdün hangi şubeden geldiğini bulma" bölümünde açıklandığı gibi git branch --contains <commit>, bir başlangıç olsa bile, söz konusu taahhüdün yapıldığı şubeyi (şubeleri yeniden adlandırabilir, taşıyabilir, silinebilir ...) kolayca tespit edemeyeceğinizi unutmayın .

  • Şube ve liste şubesini git branch --contains <commit>listelemeden, taahhütten taahhüte geri dönebilirsiniz ,featuredevelop
  • SHA1 taahhüdünü /refs/heads/develop

Eğer iki kişi id eşleşmesi yaparsa, gidebilirsiniz (bu da featureşubenin kökeni HEAD'de olduğu anlamına gelir develop).


6

JoeChrysler'in komut satırı büyüsü basitleştirilebilir. İşte Joe'nun mantığı - kısalık için , her iki versiyona cur_branchda komut ikamesi yerine bir parametre ekledim `git rev-parse --abbrev-ref HEAD`; şu şekilde başlatılabilir:

cur_branch=$(git rev-parse --abbrev-ref HEAD)

Öyleyse, Joe'nun boru hattı:

git show-branch -a           |
  grep '\*'                  | # we want only lines that contain an asterisk
  grep -v "$cur_branch"      | # but also don't contain the current branch
  head -n1                   | # and only the first such line
  sed 's/.*\[\(.*\)\].*/\1/' | # really, just the part of the line between []
  sed 's/[\^~].*//'            # and with any relative refs (^, ~n) removed

Göreceli olarak basit bir awkkomutta bu komut filtrelerinin beşiyle aynı şeyi başarabiliriz :

git show-branch -a |
  awk -F'[]^~[]' '/\*/ && !/'"$cur_branch"'/ {print $2;exit}'  

Bu böyle yıkılıyor:

-F'[]^~[]' 

En alanlara hattını bölmek ], ^, ~, ve [karakterler.

/\*/                      

Yıldız işareti içeren satırları bulma

&& !/'"$cur_branch"'/

... ancak geçerli şube adı değil

{ print $2;               

Böyle bir satır bulduğunuzda, ikinci alanını (yani alan ayırıcı karakterlerimizin birinci ve ikinci tekrarları arasındaki kısım) yazdırın. Basit dal isimleri için, bu parantezler arasında olacak; göreli sıçramalara sahip referanslar için, yalnızca değiştiricisiz ad olacaktır. Böylece alan ayırıcılar setimiz her iki sedkomutun amacını da ele alır .

  exit }

Sonra hemen çıkın. Bu, yalnızca ilk eşleşen satırı işlediği anlamına gelir, bu nedenle çıktıyı kanalize etmemiz gerekmez head -n 1.


3
Çok fazla ref nedeniyle bazı dalların çıktıda eksik olabileceğini unutmayın. Bunun yerine stderr'de uyarılar olarak gösterilirler.
Zitrax

5

İşte Mark Reed'in çözümünün bir PowerShell uygulaması:

git show-branch -a | where-object { $_.Contains('*') -eq $true} | Where-object {$_.Contains($branchName) -ne $true } | select -first 1 | % {$_ -replace('.*\[(.*)\].*','$1')} | % { $_ -replace('[\^~].*','') }

5

Bunun bu sorunu çözmenin iyi bir yolu olduğunu söylemiyorum, ancak bu benim için işe yarıyor gibi görünüyor.

git branch --contains $(cat .git/ORIG_HEAD) Sorun, bir dosyaya gitmen git'in iç çalışmasına göz atmasıdır, bu nedenle ileriye dönük (veya geriye dönük) olması gerekmez.


3

Ant ile platformlar arası uygulama

    <exec executable="git" outputproperty="currentBranch">
        <arg value="rev-parse" />  
        <arg value="--abbrev-ref" />  
        <arg value="HEAD" />  
    </exec>

    <exec executable="git" outputproperty="showBranchOutput">
        <arg value="show-branch" />  
        <arg value="-a" />  
    </exec>

    <loadresource property="baseBranch">
      <propertyresource name="showBranchOutput"/>
          <filterchain>
            <linecontains>
              <contains value="*"/>
            </linecontains>
            <linecontains negate="true">
              <contains value="${currentBranch}"/>
            </linecontains>
            <headfilter lines="1"/>
            <tokenfilter>
                <replaceregex pattern=".*\[(.*)\].*" replace="\1"/>
                <replaceregex pattern="[\^~].*" replace=""/>
            </tokenfilter>
          </filterchain>
    </loadresource>

    <echo message="${currentBranch} ${baseBranch}" />

2

@ Mark Reed: Ekleme satırının sadece bir yıldız işareti içermediğini, aynı zamanda bir yıldız işareti ile başlayacağını da eklemelisiniz! Aksi takdirde, bir yıldız işareti içeren tamamlama mesajları da eşleşen satırlara dahil edilir. Bu yüzden olmalı:

git show-branch -a | awk -F'[]^~[]' '/^\*/ && !/'"$current_branch"'/ {print $2;exit}'

veya uzun versiyon:

git show-branch -a           |
  awk '^\*'                  | # we want only lines that contain an asterisk
  awk -v "$current_branch"   | # but also don't contain the current branch
  head -n1                   | # and only the first such line
  sed 's/.*\[\(.*\)\].*/\1/' | # really, just the part of the line between []
  sed 's/[\^~].*//'            # and with any relative refs (^, ~n) removed`

2
vbc=$(git rev-parse --abbrev-ref HEAD)
vbc_col=$(( $(git show-branch | grep '^[^\[]*\*' | head -1 | cut -d* -f1 | wc -c) - 1 )) 
swimming_lane_start_row=$(( $(git show-branch | grep -n "^[\-]*$" | cut -d: -f1) + 1 )) 
git show-branch | tail -n +$swimming_lane_start_row | grep -v "^[^\[]*\[$vbc" | grep "^.\{$vbc_col\}[^ ]" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'

Mark Reed'in cevabı ile aynı amaçlara ulaşıyor, ancak birkaç senaryoda yanlış davranmayan daha güvenli bir yaklaşım kullanıyor:

  1. Ana şubenin son taahhüdü birleştirme ve sütun gösterimini yapma - değil*
  2. Tamamlama mesajı şube adı içeriyor
  3. Tamamlama mesajı şunları içerir *

0

Bu günlerde bunu yapmak isteyen herkes - Atlassian'ın SourceTree uygulaması, şubelerinizin birbirleriyle nasıl ilişkili olduğu, yani Nerede başladıkları ve şu anda taahhüt sırasına nerede oturdukları (örn. HEAD veya 4 komisyon, vb.) .


0

Kaynak Ağacı kullanıyorsanız, taahhüt ayrıntılarınıza> Ebeveynler> 'e bakın, ardından taahhüt numaralarının altı çizili olduğunu görürsünüz (bağlantılar)


0

Bir alternatif: git rev-list master | grep "$(git rev-list HEAD)" | head -1

Hem benim şubem hem de master(ya da belirtmek istediğiniz herhangi bir şube) olduğu son taahhüdü alın


0

Böyle bir şey yaptığımda bu benim için işe yaramadı develop > release-v1.0.0 > feature-foo, geliştirmek için geri dönecekti, dahil bir rebase olduğunu not et, sorunumu birleştirip birleştirmediğinden emin değilim ...

Aşağıdaki benim için doğru taahhüt hash verdi

git log --decorate \
  | grep 'commit' \
  | grep 'origin/' \
  | head -n 2 \
  | tail -n 1 \
  | awk '{ print $2 }' \
  | tr -d "\n"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.