Git - Comment trouver le premier commit d'une branche spécifique

91

Dans l'exemple d'arborescence suivant:

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

Je cherche F - le premier commit dans la branche xxx. Je pense que c'est possible avec:

git log xxx --not master

et le dernier commit listé devrait être F. Est-ce la bonne solution ou peut-être y a-t-il quelques inconvénients?

Je sais qu'il y avait des questions similaires sur stackoverflow, mais personne n'a proposé une telle solution, et je ne sais pas si je le fais correctement.

user2699113
la source
Copie

Réponses:

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

Où «succursale» est le nom de votre succursale. Le point-point vous donne tous les commits que la branche a et que le maître n'a pas. tail -1renvoie la dernière ligne de la sortie précédente.

Konyak
la source
3
cela ne fonctionne que si `` branch '' existe. Comment feriez-vous si la branche est supprimée?
Oz123
2
La branche @ Oz123 peut être remplacée par n'importe quelle référence, comme HEAD ou un sha1 ou une balise. Mais évidemment, vous avez besoin d'une sorte de référence.
Zitrax
3
Ne me donne pas ce que j'attendais. Ma branche (l'ancienne) a déjà été fusionnée avec master, ce qui signifie que tous les commits dans xxx sont déjà dans master. Pourtant - j'ai besoin de savoir quel commit ÉTAIT le premier sur cette branche - ou en fait - j'ai besoin d'examiner l'historique des commits de cette branche seule - je me fiche de savoir s'ils sont sur master ou non.
Motti Shneor
1
@MottiShneor selon la façon dont vous avez fusionné, cela pourrait être délicat. Si vous avez fait une avance rapide, c'est comme si la branche n'avait jamais existé. Sinon, vous pourriez être intéressé par cette réponse , qui répertorie un certain nombre de façons de trouver le point de branchement. Une fois que vous avez votre point de branche, le SHA peut le remplacer master, et tant que votre branche n'a pas été supprimée, il git log <sha>..branch --oneline | tail -1devrait toujours vous donner les résultats que vous recherchez.
ND Geek
1
Vous pouvez utiliser --reversepour lire les journaux à l'envers avec des couleurs, etc.
Dominik
8

Vous devez utiliser la merge-basefonctionnalité conçue pour résoudre exactement cela:

git merge-base remotes/origin/<branch> develop 
Fabrizio Stellato
la source
Je ne pense pas que cela fonctionnera si vous souhaitez revenir au point de fourche d'origine. Si vous fusionnez develop dans <branch>, la base de fusion sera plus récente que le point de fourche d'origine.
Alexander Mills
5
De plus, cela ne pointerait pas vers F, mais vers un commit dans la branche master (bien que difficile à voir dans le dessin d'OP, semble être B ou C).
RomainValeri
4
git cherry master -v | head -n 1
Nelu
la source
1

Si votre branche (ancienne) de nouveau fusionnée avec master ne donne pas le résultat attendu, j'utilise un script python pour trouver l'ID de validation de la branche initiale.

git rev-list --first-parent changeset

--premier parent ne suit que le premier commit parent en voyant un commit de fusion.

Itérer l'ensemble de modifications de la commande ci-dessus jusqu'à ce que la branche parente soit trouvée.

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
la source
0
git cherry master -v | tail -1   

cependant cela ne vous donnera que le premier commit sur la branche xxx qui n'est pas dans master, pas le premier commit sur la branche xxx jamais. ce dernier serait difficile si la branche xxx a été supprimée et / ou recréée une ou plusieurs fois. dans ce cas, vous pouvez essayer ce qui suit:

git reflog | grep checkout | grep xxx | tail -1   
Doc Unid
la source
3
Vouliez-vous écrire head -n 1au lieu de tail -1? tail -1renvoie le commit le plus récent au lieu du premier.
Nelu
-1

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

mercredis
la source
Dans mon repo, cela montre le premier commit depuis la dernière fusion du master dans la branche xxx, pas le premier commit de la branche xxx.
jk7