2016-08-06 9 views
0

Есть ли способ увидеть, для определенного репо и ветки, как изменилась эта ветка с течением времени, в том числе история переписывает? Например:Как я могу увидеть, как ветвь Git изменилась со временем (в том числе перезаписи истории)?

1 апреля: Commit A -> B -> C -> D

2 апреля, Макс Heiber- git push -f: Commit A -> B -> C»

3 апреля , Кто-то else- git merge feature Commit A -> B -> C ' ->D'

Вот почему я спрашиваю:

Мы объединили функции в нашу ветку dev, но позже изменения исчезнут с dev. Мы выяснили, что причина в том, что один из наших разработчиков делают git push -f и имела в своем .gitconfig:

[push] default = matching

Это оказало влияние силы толкания всю его ветвь, в том числе устаревших версий dev.

Понадобилось время, чтобы понять, что это происходит. То, что мы действительно хотели, в то время как устранение неполадок было связано с тем, как и почему изменилась наша история. Возможно ли получить такой вид ветки?

ответ

2

Git на самом деле не сохраняет эту информацию. Если у вас есть логги, он сохраняет что-то, для времени истечения reflog. По умолчанию эти 30 дней и 90 дней, для недостижимых и достижимых целей, соответственно. Поэтому Gerhard Poul's answer будет работать на ваш местный dev, и потому, что reflogs обычно включен даже для дистанционного отслеживания ветвей, вы можете также использовать git reflog show origin/dev, чтобы посмотреть на то, что ваш Git записал во время его git fetch/git pull операций.

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

Если на вашем сервере включены блокировки, по умолчанию они равны , а не - вы можете войти на свой сервер и запустить там git reflog show dev.

Во всех случаях вы можете добавить --date=<format> (например., --date=iso), чтобы получить {@n} заменен @{date}:

$ git reflog --date=iso master 
11ae6ca [email protected]{2016-06-17 13:32:00 -0700}: reset: moving to HEAD^ 
3d9eb53 [email protected]{2016-06-17 13:31:44 -0700}: commit: Revert "fdmillion: repair example" 
11ae6ca [email protected]{2016-04-22 05:27:07 -0700}: commit (amend): add run-checks script 
becf391 [email protected]{2016-04-22 05:24:48 -0700}: commit: add run-checks script 

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


Это технически нонсенс. :-) Commits-well, все объекты Git, действительно, являются доступными или недоступными, но записи в журнале делают их доступными, поэтому этот конкретный бит стенограммы может быть озадачивающим. Фактическое определение - , достигаемое от текущего значения соответствующей ссылки. То есть, когда git reflog expire истекает срок ссылки, он смотрит на это:

  • это reflog вход для refs/heads/foo
  • , что делает совершить филиал foo имя? (назовите это H для головы)
  • что зафиксировать это имя для регистрации reflog? (Назовем это E для записи)
  • является Е предком H? (См git merge-base --is-ancestor)
  • если да, то используйте gc.reflogExpire или gc.<pattern>.reflogExpire
  • если нет, используйте gc.reflogExpireUnreachable или gc.<pattern>.reflogExpireUnreachable

Два имени не профилированного по умолчанию 90.days.ago и 30.days.ago соответственно (значения модели не установлены по умолчанию). Есть специальный случай для refs/stash, который установлен на never.

2

Я не уверен, будет ли это работать на вашем удаленном репозитории, но оно должно по крайней мере работать на вашем локальном репо.

Чтобы посмотреть, что было сделано на Dev филиала:

git reflog show dev 

Это должно показать вам изменения в этой отрасли в течение последних 30 дней.

+0

Я проверил переписывание местной истории с помощью 'git pull -r' и посмотрел, что говорит reflog. В этом случае у меня есть лучший отзыв, который у меня есть, что фиксация «потеряна» в том, что последняя SHA такая же, как и более ранняя SHA. Это хорошо, но не то, что я заметил бы сразу.Вставка минимального reflog, который показывает это, извините за fmt: 'b21e39b HEAD @ {1}: rebase finished: возврат к refs/heads/master // b21e39b HEAD @ {2}: pull -r origin dev: checkout b21e39b921adaeb18712b5b00c62d58d20812ce1// b94d674 HEAD @ {3}: commit: second commit // b21e39b HEAD @ {4}: commit: first commit' –

+0

Да, вы не заметите этого сразу. Возможно, вы захотите воспользоваться возможностью [отключить принудительные нажатия] (http://stackoverflow.com/questions/1754491/is-there-a-way-to-configure-git-repository-to-reject-git-push -force) к ветвям, которые важны для вас. –

1

Учитывая, что локальный рефлог может быть утерян, в случае, если локальное репо было удалено сразу после принудительного нажатия, я попытался найти историю ветки, которая была обновлена ​​силой в удаленном репо.

Сделайте новый клон удаленного репо и запустите git gc так, чтобы все достижимые коммиты и связанные объекты были упакованы, а недоступные остались свободными объектами, которые можно увидеть в .git/objects. Однако я просто не могу найти команду git для перечисления этих недостижимых объектов. git rev-list кажется неспособным перечислить недостижимые объекты. Поэтому я попробовал метод dumm, чтобы перечислить их все, присоединив имя первой 2-байтной папки и левое 38-байтовое имя файла в полный sha1 один за другим. Затем используйте git cat-file -t <object> один за другим, чтобы найти все объекты фиксации. Затем запустите git show <commit-object>, чтобы увидеть их всех. Я думаю, что среди них вы могли бы найти фиксацию, на которую указывала ветка, до обновления силы.

Когда обнаружен предыдущий совет, потерянная история может быть возвращена.

+0

Не будет 'git gc' уничтожить недостижимые коммиты? Что означает «упакованный»? –

+1

@mheiber В этом случае они не будут уничтожены, если мы не добавим такой параметр, как '--prune = now', потому что они еще не истекли. Чтобы сэкономить место и быть более эффективным, Git удаляет свободные объекты и компонует их в файлы '.pack', с файлами' .idx' для сопоставления. – ElpieKay