git rebase без изменения отметок времени коммита - PullRequest
136 голосов
/ 04 июня 2010

Имеет ли смысл выполнить git rebase при сохранении отметок времени коммита?

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

Если это теоретически возможно, то возможно ли на практике с помощью rebase не изменять временные метки?

Например, предположим, у меня есть следующее дерево:

master <jun 2010>
  |
  :
  :
  :     oldbranch <feb 1984>
  :     /
oldcommit <jan 1984>

Теперь, если я перебазирую oldbranch на master, дата принятия изменится с февраля 1984 года на июнь 2010 года. Можно ли изменить это поведение, чтобы отметка времени фиксации не изменилась? В итоге я бы получил:

      oldbranch <feb 1984>
      /
 master <jun 2010>
    |
    :

Это имело бы смысл вообще? Разрешено ли даже в git иметь историю, в которой старый коммит имеет более свежий коммит в качестве родителя?

Ответы [ 4 ]

128 голосов
/ 04 июня 2010

Обновление за июнь 2014 года: Дэвид Фрейзер упоминает в комментариях решение также подробно описано в " Изменение временных меток при перебазировании git branch " с использованием опции --committer-date-is-author-date (впервые введено в январе 2009 года в коммит 3f01ad6

Обратите внимание, что опция --committer-date-is-author-date, похоже, оставляет метку времени автора и устанавливает метку времени коммиттера такой же, как и оригинальная метка времени автора, что и было OP Olivier Verdier .

Я нашел последний коммит с правильной датой и сделал:

git rebase --committer-date-is-author-date SHA

См. git am:

--committer-date-is-author-date

По умолчанию команда записывает дату из сообщения электронной почты в качестве даты автора коммита и использует время создания коммита в качестве даты коммиттера.
Это позволяет пользователю лгать о дате коммиттера, используя то же значение, что и дата автора .


(Оригинальный ответ, июнь 2012 г.)

Вы можете попробовать для неинтерактивного rebase

git rebase --ignore-date

(из этого ТА ответа )

Передается git am, в котором упоминается:

 --ignore-date

По умолчанию команда записывает дату из сообщения электронной почты в качестве даты автора коммита и использует время создания коммита в качестве даты коммиттера.
Это позволяет пользователю лгать о дате автора, используя то же значение, что и дата коммиттера.

Для git rebase этот параметр «несовместим с параметром --interactive».

Поскольку вы можете по желанию изменить временную метку старой даты фиксации git filter-branch), я полагаю, вы можете организовать свою историю Git с любым порядком дат фиксации, который вы хотите / нужно даже установить его на будущее! .


Как Оливье упоминает в своем вопросе, дата автора никогда не изменяется при перебазировании;
Из Pro Git Book :

  • Автор - человек, который первоначально написал работу,
  • тогда как коммиттер - это человек, который последним применил работу.

Итак, если вы отправите патч в проект, и один из основных участников применит патч, вы оба получите кредит.

Для большей ясности, в данном случае, как замечает Оливье:

--ignore-date делает противоположное тому, что я пытался достичь !
А именно, он стирает метку времени автора и заменяет ее метками времени коммитов!
Поэтому правильный ответ на мой вопрос:
Ничего не предпринимайте, поскольку git rebase на самом деле не меняет отметки времени авторов по умолчанию.


113 голосов
/ 24 июня 2012

Если вы уже испортили даты фиксации (возможно, с ребазингом) и хотите сбросить их до соответствующих дат автора, вы можете выполнить:

30 голосов
/ 14 июня 2011

Важный вопрос о фон С помог мне понять, что происходит: когда ваша перебазировка, отметка времени коммиттера изменяется, но не авторская отметка автора, которая внезапно становится понятной. Так что мой вопрос на самом деле не был достаточно точным.

Ответ заключается в том, что rebase на самом деле не меняет временные метки автора (вам не нужно ничего делать для этого), что мне идеально подходит.

13 голосов
/ 22 октября 2013

По умолчанию git rebase установит метку времени коммиттера на время, когда Новый коммит создан, но сохраните временную метку автора. Большая часть времени, это желаемое поведение, но в некоторых случаях мы не хотим менять метка времени коммитера тоже. Как мы можем сделать это? Ну вот трюк, который я обычно делаю.

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

Перед перебазированием запишите метку времени коммиттера, метку автора и сообщение о коммите всех коммитов, которые будут перебазированы в файл.

#NOTE: BASE is the commit where your rebase begins
git log --pretty='%ct %at %s' BASE..HEAD > hashlog

Тогда позвольте фактической перезагрузке иметь место.

Наконец, мы заменяем метку времени текущего коммиттера на метку, записанную в файле, если сообщение фиксации совпадает с использованием git filter-branch.

 git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%at %s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_COMMITTER_DATE=$__date || cat'

Если что-то пойдет не так, просто оформите git reflog или все refs/original/ ссылки.

Furthormore, вы можете сделать то же самое, что и временная метка автора.

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

git log --pretty='%at %s' COMMIT1..COMMIT2 > hashlog
join -1 1 -2 1 <(cat hashlog | cut -f 1 | sort -nr | awk '{ print NR" "$1 }') <(cat hashlog | awk '{ print NR" "$0 }') | cut -d" " -f2,4- > hashlog_
mv hashlog_ hashlog
git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_AUTHOR_DATE=$__date || cat'
...