2013-04-11 3 views
7

Пусть следующий график:Как я могу найти первую фиксацию ветки?

A -- B -- C -- D -- E -- F 
     \ 
     G -- H -- I 

Я хотел бы найти G для того, чтобы иметь возможность интерактивного Rebase сквош коммиты (но по-прежнему держать один фиксации на тему ветви), которые будут рассмотрены и объединены позже. Я не хочу просто переустанавливать всю ветку, потому что я хочу сохранить информацию о том, что есть ветка, и она была объединена.

(Я знаю, что я могу посмотреть историю и просто использовать контрольную сумму SHA для фиксации, но я ищу способ сделать это, не вручную выкапывая информацию или считая, сколько коммитов было сделано и использует ~ от HEAD с этим номером).

Edit: уточнение того, что я хочу добиться:

Я хочу, чтобы избежать этого:

A -- B -- C -- D -- E -- F -- J 
     \     /
     G -- H -- I -- -- -- - 

И есть что-то вроде этого, вместо:

A -- B -- C -- D -- E -- F -- J 
     \     /
     G' -- -- -- -- -- -- - 

Другими словами, я хотите выкачать коммиты с интерактивной перестановкой в ​​ветке темы в одну, но все равно сохранить ветвь и использовать регулярное слияние для интеграции изменений из ветви темы в мастер.

+0

См http://stackoverflow.com/questions/1527234/find-a-branch-point-with-git –

+1

Это другой вопрос. Это объясняется так же, как и я. Если мы переведем его на мой пример, он ищет 'B', но я ищу' G'. –

ответ

11

Нет коммитов "на ветке" в git. Есть только коммиты достижимый от филиала. И эта информация не является очень хорошим показателем того, из какой ветви, изначально принадлежавшей команде. Таким образом, я вижу два способа интерпретации вашего вопроса:

  • Я хочу, чтобы найти первое обязательство после слияния-основания branch и master, который находится на стороне ветви.
  • Я хочу найти первое совершение, которое доступно от branch, но не от master.

Я предполагаю, что вы имели в виду вторую. Ответ на этот вопрос будет возвращен с помощью этой команды:

git rev-list ^master mybranch | tail -n 1 

Примечания: Это все будут терпеть неудачу ужасно, если вы ответвляетесь тема ветки.


Я немного смущен относительно того, чего вы хотите достичь. Если вы хотите, целая отрасль будет представлена ​​одна совершить, но все-таки получить слияние, Вы должны сделать это:

git checkout mybranch 
git reset --soft `git merge-base mybranch master` 
git commit -m 'All of Mybranch' 
git checkout master 
git merge --no-ff mybranch 

Обратите внимание, что это будет начать сквош на первой слияния базы. Возможно, это не то, что вы хотите, если вы объединили master в mybranch. Вы можете изменить это, чтобы начать на первой фиксации на mybranch, но не на хозяина (может иметь странные и неожиданные результаты в сложных историй), заменив вторую команду с этим:

git reset --soft `git rev-list ^master mybranch | tail -n 1`^ 
+0

Спасибо. Я добавил объяснение того, что я хочу сделать, см. Мои изменения. –

+0

Я так предположил - это именно то, что я объясняю в своем ответе. – Chronial

+0

Отлично, это работает очень хорошо. Спасибо. –

4

вы получите B с git merge-base

git merge-base F I 

Или еще проще с

git merge-base my_branch my_other_branch 

Вы можете перебазироваться в результате

git rebase -i B 

И просто держать первое обязательство G, в то время как раздавить всех остальных.

+0

Это очень умно. –

1

git merge-base даст вам B. Вы хотите, чтобы все прямые дети B были также предками I. Это связано с How do I find the next commit in git? и Referencing the child of a commit in Git. Попробуйте что-то вроде:

root=$(git merge-base master topic-branch) 

git rev-list --parents ^$root topic-branch | grep " $root" | cut -f1 -d' ' 

Это список всех коммитов от корня до кончика topic-branch вместе со своими родителями и показать те, где родитель одно и merge-base корня.

Поскольку ветка темы может содержать слияния, может быть более чем одно «первое» совершение в ветви, топологически.

Смежные вопросы