Reputation: 1824
Assume we contributors who are using the Github workflow. That is, there are three repos:
Let's say we locally create a topic-branch, do a series of commits, push those commits to our origin, and open a pull request on Github. The pull request will list those commits and we wait for the owner to respond.
Imagine we identify a mistake in all (or some) of the just pushed commit messages.
Would editing those commit messages (using an interactive rebase e.g. git rebase -i HEAD~3
) and then force pushing those changes (git push --force
) ever be harmful in either case:
?
I ask in the light of general warnings against git push --force
. For example at https://help.github.com/articles/changing-a-commit-message/ there's ...
We strongly discourage force pushing, since this changes the history of your repository. If you force push, people who have already cloned your repository will have to manually fix their local history.
But in a github/integration-manager workflow context (as opposed to a Centralized workflow) that warning wouldn't seem to apply given that others are not usually forking your project.
So some ancillary questions seem pertinent:
--force-with-lease
(See https://developer.atlassian.com/blog/2015/04/force-with-lease/) further guarantee safety?Upvotes: 1
Views: 1023
Reputation: 1824
In the light of @torek's helpful comments I'll try and sharpen the question, "Is git push --force
ever harmful when applied to your origin contributor fork in Github workflow?", before attempting to answer it myself.
Consider two scenarios where you might be tempted to rebase. When you want to:
Neither kind of rebasing is a problem if you have not yet pushed commits to a public repo.
Consider, however, when you have already pushed commits to a public repo and you want to revise them:
When you want to change your files that contradict prior commits there's no problem in just incorporating those changes into a new commit (or commits), or performing a git revert
which rewinds changes through creating new commit(s). That is, rebasing is unnecessary in this scenario. (I take it when torek is exemplifying a collaborative approach to pull requests, as on the Linux mailing list, torek wants to pick out this case).
When you want to change only prior commit messages. The motive for this could be that the prior commit message(s) could wrongly identify the files changed, or otherwise wrongly describe the commit(s). You'd rather have the right message in the history in order not to confuse future readers.
So the only scenario to further consider is when you want only to change prior commit messages. Then there are further specific scenarios to consider under the Github workflow. Those with respect to the pull request against which you are tempted to push rebased commits:
The pull request is open.
a. And the project owner has pulled down commits from the pull request in order to evaluate the pull request. (Thanks again @torek for alerting me to this case).
The pull request has been merged by the project owner.
The pull request has been closed (without a merge by the project owner).
Do any of these scenarios cause harm?
I've preformed some experiments with Github accounts as an owner and contributor against scenario 1a. I've seen that it gets messy very quickly at the owner's end and the contributor's end. The mess entails that:
Although I can make both sides return to a equivalent state eventually, it becomes tricky to get there. The right combination of pushes, pulls and merges are somewhat labyrinth.
And because I've deliberately chosen to see what the messy state looks like, and not to clean things up as suggested by torek ...
if you use
git rebase
to switch back to your original chain of commits, and the message is the only thing that changed, rebase will automate the soothing of this heartburn
... I've seen that the messy state in effect duplicates the commits that were rebased; and it's not clear, just by a quick look at the commit log ...
[Owner: John Creator; contributor: John Luke Bentley]
... which set of commits are the relevant ones. That confusion exists in both the owner's local repo and the contributor's local repo (because they are now in an equivalent state).
That's enough to not even bother considering scenarios 2 and 3.
Given that confusion and mess I think it is probably best to adhere to the general advice ...
Do not rebase commits that exist outside your repository. (Chacon and Straub 2014, ch. 3 Git Branching, sec. Rebasing, 119) ...
[You could] rebase local changes you’ve made but haven’t shared yet before you push them in order to clean up your story [if necessary], but never rebase anything you’ve pushed somewhere. (Chacon and Straub 2014, ch. 3 Git Branching, sec. Rebasing, 124).
In short, avoid git push --force
(or git push --force-with-lease
) ... unless you have some exceptional reason for doing so and know what you are doing.
For noobs like me who don't know what they are doing that translates into two (relatively) simple rules:
git push --force
(nor git push --force-with-lease
); andIt might be better to view commits already pushed outside your repo just like emails that have been sent: they are out in the world for good or ill. The best strategy for correcting commits, for content or just the message, is to send an additional addendum, either as:
I'd be very much open to others posting alternative answers or providing further comment.
Upvotes: 1