Git - como encontrar o primeiro commit de um branch específico

91

Na seguinte árvore de exemplo:

A-B-C-D-E (master branch)
    \
     F-G-H (xxx branch)

Estou procurando por F - o primeiro commit no ramo xxx. Acho que é possível com:

git log xxx --not master

e o último commit listado deve ser F. É a solução correta ou talvez haja algumas desvantagens dela?

Eu sei que houve perguntas semelhantes sobre stackoverflow, mas ninguém propôs tal solução, e não tenho certeza se fiz isso direito.

user2699113
fonte
Possível duplicata de stackoverflow.com/questions/6058308/…
nyzm

Respostas:

109
git log master..branch --oneline | tail -1

Onde "branch" é o nome do seu branch específico. O ponto-ponto dá a você todos os commits que o branch tem e que o master não tem. tail -1retorna a última linha da saída anterior.

konyak
fonte
3
isso só funciona se existir `branch``. Como você faria se o branch fosse excluído?
Oz123
2
O branch @ Oz123 pode ser substituído por qualquer ref, como HEAD, sha1 ou tag. Mas obviamente você precisa de algum tipo de referência.
Zitrax de
3
Não me dá o que eu esperava. Meu branch (antigo) já foi mesclado de volta ao master, o que significa que todos os commits em xxx já estão no master. Ainda assim - eu preciso saber qual commit foi o primeiro naquele branch - ou na verdade - eu preciso examinar o histórico de commits daquele branch sozinho - não me importo se eles estão no master ou não.
Motti Shneor
1
@MottiShneor dependendo de como você mesclou, isso pode ser complicado. Se você fez um avanço rápido, é como se o galho nunca tivesse existido. Caso contrário, você pode estar interessado nesta resposta , que lista várias maneiras de localizar o ponto de ramificação. Depois de ter seu ponto de branch, o SHA pode substituí-lo mastere, contanto que seu branch não tenha sido excluído, git log <sha>..branch --oneline | tail -1ainda deve fornecer os resultados que você está procurando.
ND Geek
1
Você pode usar --reversepara ler os logs de trás para frente com cores, etc.
Dominik
8

Você deve usar a merge-basefuncionalidade projetada para resolver exatamente isso:

git merge-base remotes/origin/<branch> develop 
Fabrizio Stellato
fonte
Eu não acho que isso funcionará se você deseja voltar ao ponto de bifurcação original. Se você mesclar desenvolver em <branch>, a base de mesclagem será mais recente que o ponto de bifurcação original.
Alexander Mills,
5
Além disso, isso não apontaria para F, mas para um commit no branch master (embora seja difícil de ver no desenho do OP, parece ser B ou C).
RomainValeri
4
git cherry master -v | head -n 1
Nelu
fonte
1

Se o seu branch (antigo) mais uma vez mesclado de volta ao master não der o resultado esperado, usei o script python para encontrar o ID de commit inicial do branch.

git rev-list - conjunto de alterações primeiro-pai

--first-parent segue apenas o primeiro commit pai ao ver um commit de mesclagem.

Iterar changeset do comando acima até que o branch pai seja encontrado.

def status_check(exec_command, exec_dir=None, background=False):
    if exec_dir:
        os.chdir(exec_dir)
    res = subprocess.Popen(exec_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if not background:
        result = res.communicate()
    return result



def findNewBranchCommits(changeset=None):
    cmd = "git rev-list --first-parent "+ changeset
    rev_list = status_check(cmd,self.module_dir)
    rev_list = str(rev_list[0]).split('\n')
    rev_list = list(filter(None, rev_list))
    for x in rev_list:                      # Iterate until branch base point
        rev_cmd = "git branch --contains " + x
        rev_cmd = status_check(rev_cmd,self.module_dir)
        rev_cmd = str(rev_cmd[0]).split('\n')
        if(len(rev_cmd) > 2): 
            print "First Commit in xxx branch",x
            break

findNewBranchCommits(changeset)
Nayagam
fonte
0
git cherry master -v | tail -1   

no entanto, isso só lhe dará o primeiro commit no branch xxx que não está no master, não o primeiro commit no branch xxx de todos os tempos. o último seria difícil se o branch xxx foi excluído e / ou recriado uma ou mais vezes. nesse caso, você pode tentar o seguinte:

git reflog | grep checkout | grep xxx | tail -1   
Doc Unid
fonte
3
Você quis dizer escrever em head -n 1vez de tail -1? tail -1retorna o commit mais recente em vez do primeiro.
Nelu
-1

git rev-list --ancestry-path $(git merge-base master xxx)..xxx | tail -1

wedens
fonte
No meu repositório, isso mostra o primeiro commit desde a última mesclagem do master no branch xxx, não o primeiro commit do branch xxx.
jk7