2012-06-07 26 views
5

Powiel możliwe:
Find the parent branch of a branchZ którego oddziału Git wyszedł ten oddział?

Jak mogę się dowiedzieć, nazwę oddziału git, że oddział w pytaniu oddzielić od (jeśli w ogóle)?

+0

Masz na myśli zdalną gałąź, którą śledzi, lub gałąź, z której oddziela oddział (jeśli jest)? Nie sądzę, że zawsze możesz znaleźć to ostatnie. –

+0

Lokalny oddział, z którego ten się oddzielił (jeśli istnieje). Nie mogłem o tym powiedzieć lepiej niż ty. – Dziamid

+0

Nie sądzę, że Git nawet zapisuje te informacje, chociaż mógłbym się mylić. –

Odpowiedz

2

Łatwo jest nam myśleć master jest zawsze master i my_branch jest zawsze my_branch, ale to nie jest przypadek. Powiedzmy, że masz swoje repozytorium w Github, twoich oknach, twoim linuxie i biurze.

można zatem mieć 8 różnych oddziały:

github/master 
github/my_branch 
windows/master 
windows/my_branch 
linux/master 
linux/my_branch 
office/master 
office/my_branch 

Ty jako człowiek je zobaczyć jako master i my_branch ale git widzi je jako 8 różnych branż. Więc jeśli masz sieć takiego:

------------------------------------------------ linux/master 
\--/ \-------/ /   \-------- office/my_branch 
    | \---|--\--------/-------------------\------- my_branch 
    |  | 
    | office/master 
    | 
windows/master 

co to znaczy zapytać gdzie my_branch pochodzi? Jest wynikiem połączenia wielu gałęzi!


Tam, chciałem ci powiedzieć, że z twoim pytaniem jest problem filozoficzny. Istnieje jednak sposób, aby na nie odpowiedzieć, choć nie jest to perfekcja. Po pierwsze spójrzmy na git log:

git log my_branch --pretty=oneline --graph 

daje piękny prezentację scala i rzeczy. Ze strony git-log:

--first-parent 
    Follow only the first parent commit upon seeing a merge commit. This option can give a better overview when viewing the evolution of a particular topic branch, 
    because merges into a topic branch tend to be only about adjusting to updated upstream from time to time, and this option allows you to ignore the individual 
    commits brought in to your history by such a merge. 

Używając tego, otrzymujesz liniową historię oddziału. Usuwanie wykresu i wyprowadzanie tylko SHA1s, dostaniesz:

git log my_branch --pretty=format:"%H" --first-parent 

pomocą następującego polecenia, można powiedzieć, które gałęzie zawierają SHA1:

git branch --contains <commit> 

umieszczenie skryptu razem za pomocą tych poleceń, można użyj następującego skryptu, który w zasadzie znajduje najnowszy SHA1, który jest zawarty w innej gałęzi niż ta, którą jesteś zainteresowany. Następnie wyprowadza tę drugą gałąź. (Uwaga: Nie jestem dobry w bash skryptów jeszcze, więc to nie może być tak skuteczny):

#! /bin/bash 

if [ $# -lt 1 ]; then 
    branch=master 
else 
    branch=$1 
fi 

sha1s=$(git log $1 --pretty=format:"%H") 
res="Doesn't branch from anything" 

for i in $sha1s; do 
    b=$(git branch --contains $i | awk '{ if (NF > 1) print $2; else print $1 }') # use awk to remove * from current branch 
    other_branch=""; 
    for j in $b; do 
    if [ $branch != $j ]; then 
     other_branch=$j 
     break; 
    fi 
    done 
    if [ -n "$other_branch" ]; then 
    res=$other_branch 
    break 
    fi 
done 

printf -- '%s\n' "$res" 

powiedziałem to nie jest idealne ze względu na następującej sytuacji. Wyobraź sobie, że my_branch jest rozgałęziony od master. W rzeczywistości wtedy patrz wykres takiego:

    /------------ master 
------(master)----- 
        \------------ my_branch 

Początkowe rewizje są zawarte w historii obu oddziałów. Nie wiadomo, czy pochodziły one od mistrza. Dlatego ten skrypt powie, że my_branch został rozgałęziony od master i jednocześnie mówi, że master jest rozgałęziony od my_branch. Nie ma sposobu, aby powiedzieć, który z nich był oryginalny.