200 votes

git rebase sans changer les horodatages de commit

Serait-il judicieux d'effectuer git rebase tout en préservant la validation des horodateurs?

Je crois qu'une conséquence serait que la nouvelle direction n'auront pas nécessairement commettre les dates dans l'ordre chronologique. C'est que théoriquement possible? (par exemple, à l'aide de la plomberie des commandes; il suffit de curieux, c'est ici)

Si c'est théoriquement possible, est-il possible, dans la pratique, avec cela, de ne pas modifier le timestamp?

Par exemple, supposons que j'ai l'arbre suivant:

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

Maintenant, si je rebase oldbranch sur master, la date de la validation des modifications à partir de février 1984 à juin 2010. Est-il possible de changer ce comportement, de sorte que la validation d'horodatage n'est pas modifié? En fin de compte je voudrais donc obtenir:

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

Serait-ce que donner un sens à tout? Est-il même permis à git d'avoir une histoire où un ancien commit a une plus récente, s'engager en tant que parent?

204voto

VonC Points 414372

Mise à jour juin 2014: David Fraser mentionne dans les commentaires une solution aussi détaillée dans "Modifier les horodatages tandis que le rebasage git branch", à l'aide de l'option --committer-date-is-author-date (introduit initialement dans Janv. 2009 à commettre 3f01ad6

Notez que l' --committer-date-is-author-date option semble laisser à l'auteur d'horodatage, et de définir le livreur timestamp être le même que l'auteur original timestamp, qui est ce que l' OP Olivier Verdier voulu.

J'ai trouvé le dernier commit avec la date exacte et l'a fait:

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

Voir git am:

--committer-date-is-author-date

Par défaut, la commande enregistre la date de l'e-mail que la livraison date de création, et utilise le temps de commettre la création comme le livreur date.
Cela permet à l'utilisateur de mentir à ce sujet le livreur date en utilisant la même valeur que la date de création.


(Réponse originale à cette question, juin 2012)

Vous pourriez essayer, pour un non-interactive rebase

git rebase --ignore-date

(à partir de cette SORTE de réponse)

C'est passé de git am, qui mentionne:

 --ignore-date

Par défaut, la commande enregistre la date de l'e-mail que la livraison date de création, et utilise le temps de commettre la création comme le livreur date.
Cela permet à l'utilisateur de mentir à propos de l'auteur date en utilisant la même valeur que le livreur date.

Pour git rebase, cette option est "Incompatible avec l' --interactive option."

Depuis que vous pouvez modifier à volonté le timestamp de l'ancien commit date (avec git filter-branch- )), je suppose que vous pouvez organiser votre historique de Git avec tout ce que commettre date ordre que vous souhaitez/besoin, même le définir à l'avenir!.


Comme Olivier mentionne dans sa question, la date de création n'est jamais modifié par un rebase;
À partir de la Pro Git Livre:

  • L'auteur est la personne qui a écrit à l'origine du travail,
  • alors que le livreur est la dernière personne qui a appliqué le travail.

Donc, si vous envoyez un patch à un projet et l'un des principaux membres d'appliquer le correctif logiciel, à la fois de vous obtenir un crédit.

Pour être plus clair, dans ce cas, comme Olivier commentaires:

l' --ignore-date fait le contraire de ce que je cherchais!
À savoir, il efface l'auteur de l'horodatage et de les remplacer par les commits horodateurs!
Donc la bonne réponse à ma question est la suivante:
Ne pas faire quelque chose, depuis git rebase il n'y a pas de changement des auteurs des horodateurs par défaut.


137voto

Andy Points 2015

Si vous avez déjà foiré les dates de validation (peut-être avec une base) et que vous souhaitez les réinitialiser à leurs dates d'auteur correspondantes, vous pouvez exécuter:

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

42voto

Olivier Verdier Points 12332

Une question cruciale de Von C m'a aidé à comprendre ce qui se passe: lorsque votre base est modifiée, l'horodatage du committer change, mais pas celui de l' auteur , ce qui tout à coup prend tout son sens. Ma question n'était donc pas assez précise.

La réponse est que rebase ne change pas les horodatages de l'auteur (vous n'avez rien à faire pour ça), ce qui me convient parfaitement.

20voto

Techlive Zheng Points 807

Par défaut, git rebase va définir le livreur du timestamp au moment où l' nouveau commit est créé, mais gardez à l'auteur de l'horodatage intacte. La plupart du temps, c'est le comportement souhaité, mais à certains scénarios, nous dot souhaitez pas en changer le commiter horodatage de l'un ou l'autre. Comment pouvons-nous réaliser? Eh bien, voici la truc j'ai l'habitude de faire.

Tout d'abord, assurez-vous que chacun des commits que vous êtes sur le point de rebase est unique le message de validation(C'est là où est l'astuce besoins des améliorations, actuellement, il convient à mon les besoins).

Avant cela, enregistrement de la commiter du timestamp et le message de validation de tous les les commits qui sera relocalisée dans un fichier.

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

Ensuite,laissez le réel rebase lieu.

Enfin, nous avons remplacer l'actuel valider l'horodatage avec celle qui est inscrite dans le fichier si le message de commit est la même en utilisant git filter-branch.

 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_COMMITTER_DATE=$__date || cat' ")'

Si quelque chose va mal, il suffit de checkout git reflog ou la totalité de l' refs/original/ réf.

Furthormore, vous pouvez faire la même chose à l'auteur de l'horodatage.

Par exemple, si l'auteur de l'horodatage de certains commits sont hors de l'ordre, et sans réorganiser ces s'engage, nous voulons juste que l'auteur de l'horodatage de montrer dans l'ordre, alors les commandes suivantes vont vous aider.

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' ")'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X