2013-09-18 3 views
4

После того, как я сделаю интерактивную перезагрузку: git rebase -i HEAD~20 Я получаю новую фиксацию, например. ea1234eaСписок squashed commits

Я знаю, что история находится в рефлоге, но как я могу получить список коммитов, раздавленных в этом коммите , включая их идентификаторы (sha)?

git show ea1234ea будет отображать сообщение фиксации, в котором перечислены сообщения раздавленного, но без идентификаторов.

ответ

2

Начинается с git reflog. Результат будет выглядеть примерно так (но с более rebase -i записей):

aa4e140 [email protected]{0}: rebase -i (finish): returning to refs/heads/branch 
aa4e140 [email protected]{1}: rebase -i (squash): c1-c3, squashed 
3a422a7 [email protected]{2}: rebase -i (squash): # This is a combination of 2 commits. 
f7cac12 [email protected]{3}: rebase -i (start): checkout HEAD~3 
283263c [email protected]{4}: commit: blah yadda etc, but not a rebase 

Это последняя не- rebase линия имеет SHA1 фиксации, что был голову, прежде чем вы сделали rebase -i. На данный момент вы можете захотеть наклеить на нее временную ветку или метку, хотя это технически не требуется. Здесь я поставил легкий тег с именем temp на нем:

git tag temp 283263c 

Теперь вы можете просто запустить git log temp, или (чтобы ограничить его только те, которые вы нормированный):

git log temp --not HEAD 

или:

git log temp ^HEAD 

(эти два способа разъясняются то же самое) или:

git log -n 20 temp 

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

Когда вы закончите с временной меткой, удалите его:

git tag -d temp 

Как это работает в том, что rebase -i фактически не удалитьлюбые фиксаций, это только добавляетновый товар Commits. (Это фактически справедливо для почти каждой команды git. Исключением является процесс сбора мусора, который удаляет объекты без ссылок.)

Полный набор аргументов «commit-and-branch» для rebase (т.е. игнорирование важных вещей например -i и -p): начальная точка, предназначение и название филиала. Документация хитро замаскирует :-) первые два из них как «вверх по течению» и «на» (серьезно, «на» - это не плохое имя, и я буду придерживаться его ниже, но «восходящий поток» в некоторых случаях вводит в заблуждение).Все фиксации после начальная точка, до конца ответвление, скопированы (или опущены или раздавлены или что-то еще), по существу, по вишневым заборам, по одному за раз, как новый commit добавлен на ветку, растущую в пункте назначения. Если оригинал фиксации дерево выглядит (в частности), как это:

old -- start-point -- c2 -- c3 -- c4 <-- branch 
    \ 
     onto -- c6 -- c7     <-- another-branch 

затем запускает Rebase путем копирования (или «воспроизведение изменений из») c2 (первый фиксации после начальной точки), чтобы идентичный изменение (но с различной фиксацией информации), c2', размещая его так, что onto является его родителем:

old -- start-point -- c2 -- c3 -- c4 <-- branch 
    \ 
     onto -- c6 -- c7     <-- another-branch 
     \ 
      c2' 

Затем он копирует c3 на новую (c3') версию, с c3' «родителем является c2' и т. Д. Когда все это сделано это чистит ярлык (branch) прочь c4 и приклеивает его на указывая на последнем новый коммит (c4') вместо:

old -- start-point -- c2 -- c3 -- c4 <-- [no label] 
    \ 
     onto -- c6 -- c7     <-- another-branch 
     \ 
      c2' -- c3' -- c4'   <-- branch 

Обратите внимание, что старые коммиты (start-point, c2, c3, и c4) все еще есть, у них больше нет метки ветви. Также обратите внимание, что в этом конкретном случае (с использованием аргумента --onto, как показано, с этим конкретным деревом фиксации), фиксация с именем start-point сама становится «невидимой» (в том же смысле, что и c2 - c4), поскольку она больше не имеет ветви или тег ярлыка, указывающий на него, если, конечно, вы не установите его до или после того, как вы выполните rebase. (Как правило, есть не такой «пропускаются» совершает. Конечно, в интерактивном перебазироваться, вы можете сделать это пропустить некоторые, но это достаточно ясно, что вы имели в виду, чтобы сделать это.)

немеченым («невидимый» или «скрытый») фиксируется, пока они остаются в reflog (90 дней, если вы не измените настройку по умолчанию). Чтобы заставить их придерживаться еще дольше, установите метку - например, ветку или имя тега - чтобы указать на них. Это то, что я делаю с тегом temp выше. Теперь они снова видны и легко видны в любом инструменте-tree-viewer, таком как gitk или git log.

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


Есть много больше способов разъясняются его. Фактически, git log HEAD..temp делает трюк, хотя он выглядит неправильным, так или иначе. :-) В этих версиях все предполагают, что HEAD по-прежнему является именем ветви, на которой вы делали rebase. Если вы были на ветке squiggle, вы могли бы использовать git log temp ^squiggle, как только HEAD переместился в другое место, например.