2012-11-01 15 views
6

Ho clonato alcuni repository git e ho fatto "git branch abcd", che mi ha passato a un ramo derivato da origine/abcd. abcd non è il ramo di origine predefinito. Quindi, ho creato un ramo di funzionalità "my_feature" da abcd. Voglio fare "git merge origin/abcd" in my_feature in uno script che sarebbe applicabile indipendentemente dal nome del ramo di origine usato (o almeno applicabile a casi facili quando non ci sono strutture di branch complesse descritte in altre risposte riguardo git).Ottenere il nome del ramo di origine genitore in git?

Come individuare il ramo di origine "più prossimo"/"parent" da cui è stato creato il ramo corrente?

+0

possibile duplicato [Trova ramo genitore di un ramo] (http: // StackOverflow.com/domande/3161204/find-the-genitore-ramo-of-a-branch) – pisaruk

risposta

3

Questo è difficile da fare bene. In git, un ramo è solo un puntatore che avanza automaticamente su un commit e un commit può avere qualsiasi numero di nomi di ramo su di esso. Consideriamo questo caso:

your master:  y1---y2---y3 
       /
master: a---b---c---d---e 
       \ 
feature:   f1---f2---f3---f4 

hai estratto ramo "master" a c, e impegnata y1, y2 e y3. La tua cronologia assomiglia quindi a a b c y1 y2 y3. Nel frattempo il master è avanzato a d e e, ma qualcuno ha creato un ramo di funzionalità e ha impegnato f1 tramite f4 in base a c. Git non ha modo di stabilire che il tuo ramo provenga da master anziché da feature, quindi nella migliore delle ipotesi avrai una scelta di filiali da unire.

Se lo facessi automaticamente, dovresti applicare un'euristica per scegliere il ramo più corto, o il ramo più lungo, o quello con il più/minimo commit, o qualcos'altro come quello. Naturalmente, poiché ci sono così tante opzioni, non è davvero una buona scelta per una funzione integrata git. Tuttavia, utilizzando le funzioni di "idraulico" di Git si può scrivere il proprio:

#!/bin/bash 

# Tries to determine a good merge base from among all local branches. 
# Here used, a "good" merge base is the one sharing the most recent commit 
# on this branch. This function will exit 1 if no branch is found, 
# or exit 2 in a tie. 
# 
# Untested - use at your own risk. 

MAX_SEARCH=20 # only search the last 20 commits on this branch 
FOUND=0 
LAST_BRANCH= 

# iterate through the commits, most recent first 
for COMMIT in $(git rev-list --max-count=$MAX_SEARCH HEAD); do 
    # check every local branch 
    for BRANCH in $(git for-each-ref --format="%(refname)" refs/heads); do 
    # look for the commit in that branch's history 
    if (git rev-list $BRANCH | fgrep -q COMMIT); then 
     echo $BRANCH 
     FOUND=$((FOUND + 1)) 
     LAST_BRANCH="$BRANCH" 
    fi 
    done 
    if [ $FOUND -gt 1 ]; then 
    # more than one choice; exit 
    exit 2 
    elif [ $FOUND -eq 1 ]; then 
    git merge $LAST_BRANCH 
    exit 0 
    fi 
done 
exit 1 # could not find a parent 
2

Con un DVCS, non esiste un "ramo principale".

Un ramo è:

  • un nome
  • una partenza commit, e che commettono può:
    • parte più rami, sia dal repo locale e repository upstream come 'origin '.
    • cambiamento dopo un rebase del ramo

Vedi per più:

L'unico modo per lo script lavorare è registrare il nome dello origin/branch, preferibilmente come git notes (poiché non modifica la cronologia e gli SHA1, ma aggiunge metadati).

Problemi correlati