Update branch with rebase instead of merge - github

Is there any way to replace merge with rebase at GitHub PRs? I looked through protected branches settings but didn't find such option.

GitHub now (Feb. 2022) supports this:
More ways to keep your pull request branch up-to-date
The Update branch button on the pull request page lets you update your pull request's branch with the latest changes from the base branch.
This is useful for verifying your changes are compatible with the current version of the base branch before you merge.
Update your pull request branch by rebasing:
When your pull request's branch is out of date with the base branch, you now have the option to update it by rebasing on the latest version of the base branch.
Rebasing applies the changes from your branch onto the latest version of the base branch, resulting in a branch with a linear history since no merge commit is created.
To update by rebasing, click the drop down menu next to the Update Branch button, click Update with rebase, and then click Rebase branch.
Previously, Update branch performed a traditional merge that always resulted in a merge commit in your pull request branch. This option is still available, but now you have the choice.
Note: Because rebasing rewrites the history of the branch, if you are working with the branch locally, you will need to fetch it and do a hard reset to ensure your local branch matches the branch on GitHub.com.
Learn more about keeping your pull request in sync with the base branch.

I doubt github supports this, as you should never rebase a public branch. From the official git docs:
Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea: anyone downstream of it is forced to manually fix their history. This section explains how to do the fix from the downstream’s point of view. The real fix, however, would be to avoid rebasing the upstream in the first place.
The easiest solution would be to simply use a merge. If you don't like that for any reason, you could create a new branch from main, apply the desired changes (e.g. by using git cherry-pick, or git diff in conjunction with patch), and then delete the old branch and create a new PR. If you really want to use rebase, you can do so locally and force-push the branch, but again, that's a really bad idea as it falsifies history and breaks the branch for everybody else.

Related

Revert Pull Request in Github

I merged a pull request accidentally in github but it needs some changes how can I revert the pull request in github to add those changes that I want.
Thank you.
Open the Pull Request page: https://github.com/your_org/your_repo/pulls
Click on "Closed"
Select your PR
Click on "revert"
The best thing to do would be to simply make a new PR with the changes you want to make, as no matter what you do, the "bad" PR will always be a part of the git history. That being said, follow Vertexwhan's answer if you really want to revert the merge, but keep in mind that you will not be able to re-merge the same branch later on.
I had the same problem, revert pushed commit results in new commits that remove your code.
Then, you can't merge again the PR, these commits are already in master history so PR can't be merged again after revertion.
The solution I found and which doesn't force history :
On master, on your local repo :
git revert -m 1 <merged PR commit-hash>
The -m 1 : "specifies the parent number (starting from 1) of the mainline and allows revert to reverse the change relative to the specified parent." Keep master history clear.
https://git-scm.com/docs/git-revert
Next, you can create a new branch from master like : unrevert-<my-branch>.
On this new branch you can use git cherry-pich to restore reverted commits : git cherry-pick <commit-hash>.
Then, you can merge your unrevert-<my-branch> on your PR branch.
After it, you can reopen your PR and your commits are again mergable on master. You can continue to work on your branch like nothing happens.
That doesn't need to detach HEAD which can be complicated to deal with

New Pull Request when a previous one is pending Merge

I made some changes to several files of the project on a new branch (let's call it branch_a), I commited them, created the Pull Request, and it was recently reviewed and approved. It's still pending Merge on the master branch.
Now, someone asked for another change. It's a small supplemental change in 1 of the files edited in the first Pull Request.
What's the best way of doing this? Should I ask for the first Pull request to be merged and then create a new branch (branch_b), make my change and create a new Pull Request, ask for review and merge again?
Or is there a "cleaner" way, when the first Pull Request is somehow merged with the second one and we don't have to make 2 different merges?
If another change requested is a part of the same feature as in ‘branch_a’, then you can simply make change in the same branch, your PR request will show up those changes, but PR approval will be required again.
If another change requested is outside the scope of feature ‘branch_a’ and it is just a file is same between two changes, then you can create a new branch out of master say ‘branch_b’, complete your changes and raise PR for the same. After ‘branch_a’ is merged into master, you can rebase your second branch ‘branch_b’ to include updated master codebase into branch_b, (or vice-versa if branch_b is merged first).
This is especially useful if the order of merge is not decided in advance.
Below are the steps, for rebase, here ‘feature_branch’ is the name of your branch for which you want to perform rebase:
git checkout master
git pull origin master
git checkout feature_branch
git rebase master
Here you might get some conflicts(if there are any) multiple times as per number of commits in your feature_branch. You can resolve the conflicts manually and proceed with further process of rebase with below command:
git rebase --continue
At any point if you think that things are not going well and you would like to cancel rebase process, then execute below command:
git rebase --abort
Finally when all conflicts are resolved and you get message as successfully merged, then execute below command to push changes to origin:
git push --force origin feature_branch
for more information on rebase process follow link:
https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase
Branch off the first pull request branch, edit, add, commit, push, and ask for a second PR merging to the first branch. When the first branch is merged the second PR will be reconfigured automatically (by GitHub) to be merged into the main branch.

How to keep a GitHub fork up to date without a merge commit or using CLI?

The normal GitHub flow to contribute to a repo is to create a fork of the upstream, clone a local copy where you make changes, then push back up to your fork and then create a PR to have your changes merged into upstream.
But if upstream changes after that, how do you update your fork without creating a merge commit (and also without using the git CLI)?
I already know how to do this in a way that will create a merge commit or which depend on the git command line interface. This question is specifically about using the GitHub.com website or GitHub Desktop application only (no CLI).
Since this is a very common workflow it seems like there should be some simple way to do it using the GitHub GUI.
To reiterate: any answers that use the CLI or create a merge commit (e.g. this way) will not be answering this question since I'm explicitly looking for a non-CLI solution.
without a merge commit or using CLI?
Not directly with GitHub web UI alone, since it would involve rebasing your PR branch on top of upstream/master
So in short: no.
But in less short... maybe, if you really want to try it.
Rebasing through GitHub web UI is actually possible, since Sept. 2016, ...
if you are the maintainer of the original repo, wanting to integrate a PR branch
if none of the replayed commit introduces a conflict
(This differs from GitHub Desktop, which, since June 5th 2019 does support rebasing. But that is a frontend to Git CLI, like other tools provide. For example GitKraken and interactive rebase)
So a convoluted workaround would be:
to fetch, then push upstream/master to the master branch of your own fork (a CLI operation, but more on that below)
change the base branch of your current PR to master (so a PR within the same repository: your own fork), provided you haven't pushed to master.
Meaning: master in your fork represents the updated upstream/master, with upstream being the original repository that you have forked.
Since you are the owner of that repository (your fork), GitHub can then show you if you can rebase said branch to the base branch of the PR (master), but only if there is no conflict.
finally, change the base branch again, to <originalRepo>/master (which is the intended target of your PR)
The very first step is typically done through command line, but... there might be a trick to do it (update upstream master in your fork) through web UI: see "Quick Tip: Sync a Fork with the Original via GitHub’s Web UI" by Bruno Skvorc
In short, it involves:
creating a new branch from your current master (which would be at upstream/master at the time you forked the original repository)
Making a PR with that new branch and <originalRepo/master>
doing a base switch before creating the PR
That is the step which artificially forces upstream/master to be refreshed
You can the create and merge it with the “Merge Pull Request” button (and “Confirm Merge” afterwards): the merge will be trivial: no merge commit.
The end result is: your own master branch (in your fork) updated with upstream/master (the master branch of the original repository)!
You can then resume the steps I describe above, and change the base of your current PR to your own (now refreshed) master branch, and see if you can rebase it!
This is feasible with GitHub Desktop since version 1.0.7 considering the following:
If the current branch does not have any commits ahead upstream (the original repo of the fork), the new commits can be pulled without creating a new merge commit
In GitHub Desktop:
Clone your repository from File > Clone Repository
Fetch origin, which will automatically fetch the upstream as well
Go to Branches by clicking on where it says Current Branch
Click on Choose a branch to merge into <branch> at the bottom
Search for upstream/<branch>, then click Merge upstream/<branch> into <branch>
Push to origin, et voilà!
Otherwise, ff the current branch has commits ahead of the fork, then of course one has to create a merge commit or rebase and force push. For rebasing which might be more preferable, do the following:
In GItHub Desktop, go to Branch from menu, then Rebase Current Branch
Search for upstream/<branch>, then click Start Rebase
Solve any conflicts that have occurred from the rebase
Force push to origin. You will get a warning for this for obvious reasons.
For avoiding force-pushing to your work when your current branch is both ahead and behind its upstream counterpart, either create a new merge commit or:
Make a new branch based with all your changes
If needed, reset the original branch to its original state (before it diverged from the original repo)
Perform the steps from the first scenario and merge your changes into your branch.
And yes, it seems that pulling via the GitHub website from the original repo without creating a pull request and merge commit is not possible at this moment.
Demo GIF for first scenario: https://imgur.com/a/8wci2yf
Some GitHub issues related to this:
Add an upstream to forked repositories
multi-remote support in Desktop
Update
Note: Non-CLI based approach that might help:
Is there a way to make GitHub Desktop rebase a branch against master?
The only key here is doing a rebase, so the above answer should help.
CLI way (which is easier and using git, so it should be more comprehensive by default)
There are some practices that you should use to avoid this.
Don't work on the master branch in your fork.
$ git clone <your fork>
$ git checkout -b feature_branch
You can work in your feature_branch and then raise a Pull Request.
Once your changes are merged in the upstream master, you can pull from upstream to your origin. Since the master on upstream will have your commits sitting neatly on top of it, there won't be a merge commit.
$ git checkout master
$ git pull upstream master
$ git push origin master
In the case, where the maintainer has diverged from the master that you have in your fork, that is, it's not linear any more, you need to pull a fresh copy of it. That should not be a problem as your changes are already in the upstream.
If the master in upstream has moved ahead while you were working on your PR, then you can rebase on you feature_branch.
$ git checkout master
$ git pull upstream master
$ git push origin master
$ git checkout feature_branch
$ git rebase master
Please refer to this document for detailed reference: Fork and pull request workflow

Can mercurial pull changes from forked repo into a new branch?

I have a project, biocommons/hgvs. A contributor forked the project, made some changes, and submitted a pull request. I'd like to make some minor changes to those commits, and I'd prefer to do so in a feature branch.
Is there a way to pull the PR commits into a new branch?
You cannot pull them in another branch in a sense how mercurial uses branch (as in named branch created by hg branch).
However, you simply can continue to work on top of your latest commit and later merge your head and the head created by the pull request, thus both, yours and their head being anonymous branches. (IMHO this is the beauty - every head can work on its own, no need to expressly branch or name things)
If you still want a name, you can stick a bookmarks onto the head of the pulled changes; they work very similar to 'full' branches except that they can be changed and moved.
If you really need and want the changesets to be in a named branch, then pull from the forked repository, create the named feature branch manually and use rebase or histedit to move the commits to the just created feature branch.

GitHub fork a repo from previous commit

I've found a repository on GitHub I would like to fork - but not the current version.
I want to fork the repo as it was quite a few commits back - is this possible? The repo has not marked any releases, so I'm not sure how to do this. I could obviously copy the code as it was in that commit, but I would prefer to fork, as then I get the link back to the original repo.
You can only fork the current repository.
You can reset the forked repository's master branch to an earlier commit though, making it look like as if you had forked it at that point.
See: How can I rollback a github repository to a specific commit?
If you reset every branch, it effectively resets your repository to an earlier state of the original repository (with exception of branch-independent data, like configuration, hooks etc which are not reset). Since it's possible that not all branches contain the commit from the master branch, you might need to look up commits by date for each branch, to reset them to the last commit before the commit from which you want to fork.
I was also unable to do this using github, but Sourcetree handled it perfectly.
Switched to the desired branch.
Found the commit that I wanted as the head of my new branch and right clicked.
Selected "branch."
My commit was already selected.
Name this new branch, create, and push.
Can also be done by selecting the "branch" button.
You then select the commit that you want as your new head, give it a name, and create it.