Git rebase bez zmiany znaczników czasu zatwierdzenia

Czy miałoby sens wykonywanie git rebase przy zachowaniu znaczników czasu zatwierdzenia?

Wierzę, że konsekwencją będzie to, że nowa gałąź niekoniecznie będzie miała daty zatwierdzania chronologicznie. Czy to teoretycznie możliwe? (np. za pomocą poleceń hydraulicznych; po prostu ciekawy tutaj)

Jeśli teoretycznie jest to możliwe, to czy w praktyce z rebase można nie zmieniać znaczników czasu?

Na przykład, załóżmy, że mam następujące drzewo:

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

Teraz, jeśli zmienię oldbranch na master, Data zmian zmieni się z lutego 1984 na Czerwiec 2010. Czy można zmienić to zachowanie tak, aby znacznik czasu zatwierdzenia nie został zmieniony? W końcu otrzymałbym:

      oldbranch <feb 1984>
      /
 master <jun 2010>
    |
    :
Czy to miałoby sens? Czy jest dozwolone w git mieć historię, w której Stary commit ma nowszy commit jako rodzic?
Author: Olivier Verdier, 2010-06-04

4 answers

Aktualizacja Czerwiec 2014: David Fraser wspomina w komentarzach rozwiązanie również opisane w "Zmień znaczniki czasu podczas rebasingu git branch ", używając opcji --committer-date-is-author-date (wprowadzonej początkowo w styczniu 2014 roku). 2009 in commit 3f01ad6

Zauważ, że opcja --committer-date-is-author-date wydaje się opuszczać znacznik czasu autora i ustawiać znacznik czasu committera na taki sam, jak oryginalny znacznik czasu autora, czego chciał Olivier Verdier .

Znalazłem ostatni commit z poprawną datą i zrobiłem:

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

Zobacz git am:

--committer-date-is-author-date

Domyślnie polecenie zapisuje datę z wiadomości e-mail jako datę autora zatwierdzania i używa czasu utworzenia zatwierdzania jako daty zatwierdzania.
pozwala to użytkownikowi kłamać na temat daty committera, używając tej samej wartości co Data autora .


(oryginalna odpowiedź, czerwiec 2012)

Możesz spróbować, dla non-interactive rebase

git rebase --ignore-date

(z tego więc odpowiedz )

To jest przekazywane do git am, który wspomina:

 --ignore-date

Domyślnie polecenie zapisuje datę z wiadomości e-mail jako datę autora zatwierdzania i używa czasu utworzenia zatwierdzania jako daty zatwierdzania.
Pozwala to użytkownikowi kłamać na temat daty autora, używając tej samej wartości co Data zatwierdzającego.

Dla git rebase, ta opcja jest "Niezgodny z opcją -- interactive."

Od możesz dowolnie zmieniać znacznik czasu starej daty zatwierdzenia (z git filter-branch), domyślam się, że możesz uporządkować swoją historię Gita z dowolną kolejnością daty zatwierdzenia, nawet ustaw ją na przyszłość!.


W 2007 roku, w wyniku zmian w strukturze organizacyjnej, w 2008 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w 2009 roku, w]} Z Pro Git Book :
  • autor jest osobą, która pierwotnie napisała pracę,
  • podczas gdy committer jest osobą, która ostatnio zastosowała dzieło.

Jeśli wyślecie łatkę do projektu, a jeden z głównych członków zastosuje łatkę, oboje otrzymacie kredyt.

Żeby było wyjątkowo jasne, w tym przypadku, jak komentuje Olivier:

--ignore-date robi przeciwieństwo tego, co chciałem osiągnąć !
Mianowicie wymazuje znacznik czasu autora i zastępuje je ze znacznikami czasu commitów!
Więc właściwa odpowiedź na moje pytanie brzmi:
Nie rób nic, ponieważ git rebase domyślnie nie zmienia znaczników czasu autorów.


 113
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:01

Jeśli już spieprzyłeś daty zmian (być może za pomocą rebase) i chcesz zresetować je do odpowiadających im dat autorów, możesz uruchomić:

git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'

 109
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-08 18:00:27

Kluczowe pytanie Von C pomogło mi zrozumieć, co się dzieje: kiedy twoja rebase, znacznik czasu committera zmienia się, ale nie znacznik czasu autora , co nagle nabiera sensu. Więc moje pytanie nie było wystarczająco precyzyjne.

Odpowiedź jest taka, że rebase właściwie nie zmienia znaczników czasu autora (nie musisz nic robić), co mi pasuje idealnie.

 28
Author: Olivier Verdier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-14 08:31:35

Domyślnie, Git rebase ustawi znacznik czasu committera na czas, kiedy tworzony jest nowy commit, ale zachowuje znacznik czasu autora. Większość czasu, jest to pożądane zachowanie, ale w niektórych scenariuszach nie chcemy zmieniać znacznik czasowy też. Jak możemy tego dokonać? Cóż, oto zwykle robię sztuczki.

Najpierw upewnij się, że każdy commit, który zamierzasz zmienić, ma unikalny commit message I author timestamp (to jest gdzie trick potrzebuje ulepszenia, obecnie odpowiada moim potrzebom).

Przed zmianą bazy, Zapisz znacznik czasu zatwierdzającego, znacznik czasu autora i komunikat zatwierdzania wszystkich zmian, które zostaną ponownie zapisane do pliku.

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

Następnie, niech nastąpi prawdziwa rebase.

Na koniec zamieniamy znacznik czasu bieżącego zatwierdzającego na ten zapisany w pliku, jeśli wiadomość zatwierdzająca jest taka sama za pomocą 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'

Jeśli coś pójdzie nie tak, po prostu Kasuj git reflog lub wszystkie refs/original/ ref.

Furthormore, możesz zrobić coś podobnego do znacznika czasu autora.

Na przykład, jeśli znacznik czasu autora niektórych commitów jest nieprawidłowy, i bez przestawiania tych commitów, chcemy tylko, aby znacznik czasu autora wyświetlał się w porządku, a następnie następujące polecenia pomogą.

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'
 12
Author: weynhamz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-17 02:56:15