How to fix commit order in GitHub pull requests, broken by git rebase?

纵饮孤独 提交于 2019-12-03 14:53:18

问题


When I write code I break it into small logical changes that are easy and quick to review.

To do so, I use git rebase -i (interactive) to squash, drop and change order of commits.

I've noticed this sometimes leads to a different order of commits on a GitHub pull request (though the order is retained on the remote branch).

For example,

  • commit 1
  • commit 2
  • commit 3

might show up in the PR as:

  • commit 3
  • commit 1
  • commit 2

I've searched the internet and only managed to find this GitHub help page: Why are my commits in the wrong order? Their answer:

If you rewrite your commit history via git rebase or a force push, you may notice that your commit sequence is out of order when opening a pull request.

GitHub emphasizes Pull Requests as a space for discussion. All aspects of it--comments, references, and commits--are represented in a chronological order. Rewriting your Git commit history while performing rebases alters the space-time continuum, which means that commits may not be represented the way you expect them to in the GitHub interface.

If you always want to see commits in order, we recommend not using git rebase. However, rest assured that nothing is broken when you see things outside of a chronological order!

Is there a way to work around this?


回答1:


I've managed to work around this by:

  1. Locate the last commit that retained the order
  2. Run git rebase -i <hash of that commit>
  3. Replace all pick with reword
  4. Run git push -f

Before that, I tried changing only the first commit message, which also changes all the following hashes, but that didn't fix it.

I had to do it for every following commit too for it to work.




回答2:


To automate what Eliad suggested I use a script from Piotr:

git rebase "$(git merge-base HEAD master)" --ignore-date -x 'git commit --amend -C HEAD --date="$(date -R)" && sleep 1.05'




回答3:


How to fix commit order in GitHub pull requests, broken by git rebase?

That could be done with the (still being discussed) 2019 git evolve command:

Objective

Create an "evolve" command to help users craft a high quality commit history.

Users can improve commits one at a time and in any order, then run git evolve to rewrite their recent history to ensure everything is up-to-date.
We track amendments to a commit over time in a change graph. Users can share their progress with others by exchanging their change graphs using the standard push, fetch, and format-patch commands.

Status

This proposal has not been implemented yet.

Background

Imagine you have three sequential changes up for review and you receive feedback that requires editing all three changes.
We'll define the word "change" formally later, but for the moment let's say that a change is a work-in-progress whose final version will be submitted as a commit in the future.

While you're editing one change, more feedback arrives on one of the others.
What do you do?

The evolve command is a convenient way to work with chains of commits that are under review.
Whenever you rebase or amend a commit, the repository remembers that the old commit is obsolete and has been replaced by the new one.

Then, at some point in the future, you can run "git evolve" and the correct sequence of rebases will occur in the correct order such that no commit has an obsolete parent.

Part of making the "evolve" command work involves tracking the edits to a commit over time, which is why we need an change graph.
However, the change graph will also bring other benefits:

  • Users can view the history of a change directly (the sequence of amends and rebases it has undergone, orthogonal to the history of the branch it is on).
  • It will be possible to quickly locate and list all the changes the user currently has in progress.
  • It can be used as part of other high-level commands that combine or split changes.
  • It can be used to decorate commits (in git log, gitk, etc) that are either obsolete or are the tip of a work in progress.
  • By pushing and pulling the change graph, users can collaborate more easily on changes-in-progress.
    This is better than pushing and pulling the changes themselves since the change graph can be used to locate a more specific merge base, allowing for better merges between different versions of the same change.
  • It could be used to correctly rebase local changes and other local branches after running git-filter-branch.
  • It can replace the change-id footer used by gerrit.



回答4:


I propose a ~/.gitconfig alias like this:

[alias]                                                                            
    rewrite = rebase -x 'git commit --amend -C HEAD --date=\"$(date -R)\" && sleep 1.05'

After you completed your regular rebase -i master fixup stuff, you can then simply do a git rewrite master to fix it for GitHub commit order. It will create a new commit each second based on the old ones. By overwriting the --date it will force GitHub to keep the correct order.




回答5:


The --ignore-date option of rebase can be used to reset the author date of commits. This will fix the order of commits on github.

With a force-push, you can even fix the commit order on an existing pull request.

For example:

  1. git checkout my_pull_request_branch
  2. git rebase --ignore-date origin/master
  3. git push -f origin my_pull_request_branch


来源:https://stackoverflow.com/questions/44704519/how-to-fix-commit-order-in-github-pull-requests-broken-by-git-rebase

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!