Git - как найти первую фиксацию конкретной ветки

93

В следующем примере дерева:

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

Ищу F - первый коммит в ветке xxx. Я думаю, что это возможно с:

git log xxx --not master

и последний коммит в списке должен быть F. Это правильное решение или, может быть, у него есть некоторые недостатки?

Я знаю, что были похожие вопросы по stackoverflow, но никто не предлагал такого решения, и я не уверен, правильно ли я его делаю.

пользователь2699113
источник
Возможный дубликат stackoverflow.com/questions/6058308/…
nyzm

Ответы:

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

Где «ветка» - это ваше конкретное имя ветки. Точка-точка дает вам все коммиты, которые есть у ветки, которых нет у мастера. tail -1возвращает последнюю строку из предыдущего вывода.

коньяк
источник
3
это работает, только если существует «ветка». Как бы вы это сделали, если ветку удалили?
Oz123
2
Ветвь @ Oz123 может быть заменена любой ссылкой, например HEAD, sha1 или тегом. Но, очевидно, вам нужна какая-то ссылка.
Zitrax
3
Не дает мне того, чего я ожидал. Моя ветка (старая) уже была объединена с мастером, что означает, что все коммиты в xxx уже находятся в мастере. Тем не менее - мне нужно знать, какая фиксация БЫЛА первой в этой ветке - или на самом деле - мне нужно изучить историю коммитов только этой ветки - мне все равно, на главной они или нет.
Мотти Шнеор
1
@MottiShneor, в зависимости от того, как вы слились, это может быть сложно. Если вы сделали быструю перемотку вперед, создается впечатление, что ветки никогда не существовало. В противном случае вас может заинтересовать этот ответ , в котором перечислены несколько способов найти точку ветвления. Когда у вас есть точка ветвления, SHA может заменить master, и, пока ваша ветка не была удалена, git log <sha>..branch --oneline | tail -1все равно должен давать вам результаты, которые вы ищете.
ND Geek
1
Вы можете использовать --reverseдля чтения журналов в обратном порядке с помощью цветов и т. Д.
Доминик
8

Вы должны использовать merge-baseфункциональность, которая предназначена именно для этого:

git merge-base remotes/origin/<branch> develop 
Фабрицио Стеллато
источник
Я не думаю, что это сработает, если вы захотите вернуться к исходной точке развилки. Если вы объедините разработку в <branch>, база слияния будет новее, чем исходная точка разветвления.
Александр Миллс
5
Кроме того, это будет указывать не на F, а на фиксацию в основной ветке (хотя на чертеже OP это трудно увидеть, похоже, это B или C).
RomainValeri
1

Если ваша ветка (старая) снова слита с master, не дает ожидаемого результата, я использую скрипт python, чтобы найти идентификатор фиксации начальной ветки.

git rev-list - набор изменений первого родителя

--first-parent следовать только за первым родительским коммитом, увидев коммит слияния.

Повторяйте набор изменений из приведенной выше команды, пока не найдете родительскую ветвь.

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)
Наягам
источник
0
git cherry master -v | tail -1   

однако это даст вам только первую фиксацию в ветке xxx, которая не находится в master, но не первую фиксацию в ветке xxx. последнее будет затруднительно, если ветка xxx была удалена и / или воссоздана один или несколько раз. в этом случае вы можете попробовать следующее:

git reflog | grep checkout | grep xxx | tail -1   
Док Юнид
источник
3
Вы хотели написать head -n 1вместо tail -1? tail -1возвращает самую последнюю фиксацию вместо первой.
Нелу
0

Я попробовал эту команду, и она сработала:

git log <source_branch> <feature_branch> --oneline | tail -1
Абдеррахмен
источник
-1

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

Wedens
источник
В моем репо это показывает 1-й коммит с момента последнего слияния из мастера в ветку xxx, а не 1-й коммит ветки xxx.
jk7 02