How to split commits into individual PRs on Github - github

So this isn't your typical 'just rebase' issue (Atleast I don't think).
I'd like to know how I can create more than one pull request without effecting past commits. Here is my current scenario:
I forked a repository
I made the change on my local master (so stupid, I know)
I made a PR with the changes
They were accepted but are auto-merged by a bot in a few days
Here's the problem, I'd like to keep contributing but with individual PR's in the meantime that don't list all the old (but yet to be merged) commits I've made. My idea was to get upstream, rebase my master, and work from there (properly this time with branches). However upstream/master conflicts with master so it won't allow me to. I'm afraid to rebase my local master with the current original because I fear it may 'delete' the code for my pull request and somehow invalidate it.
Any idea how I can fix this? Or do I just have to wait for the bot to make the merge from my PR then rebase from master.

My idea was to get upstream, rebase my master
Don't: set a branch on your current local master, where you have your old (but yet to be merged) commit.
git switch -c mywip master
(wip: work in progress)
This uses the new git switch command (Git 2.23+)
Then reset master to upstream master
git fetch upstream
git switch master
git reset --hard upstream/master
Work from there, in a new branch, for a new future PR (based on a code which does not list the old -- but yet to be merged -- commits).

Related

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.

Undoing Git Branch Commit and Merge

I'm currently working on an assignment where we work on a local repository and push to a remote repository when we are done. We are expected to make use of branches, wherein we make all our commits before merging it into our master branch, so no commits directly to the master branch.
Everything was going fine, but I've come across a problem when I made some commits on a branch, then merged that branch into my master, before going back to the before-mentioned branch to make some more changes, committing them and merging it once again back into my master branch.
My network tree is currently looking like this:
network branch
The problem being the green branch that is branching off at the end with hash 2bbbd0c.
I'm essentially looking to undo that commit completely and simply have my branch merge into my master, so my network branch shows that nothing is branching off.
One idea I have is to use git reset –hard 2b32611 (which is the hash for my latest commit on the branch before merging it into my master):
enter image description here
And then to use git push -f origin 2b32611:cookies-user-tracking to push the commit and the branch, but once again I’m not sure if that’ll work, and I don’t want to mess anything up.
The git reset --hard will indeed reset cookies-user-tracking to the right commit (before merge)
All you need to do then is to force push the branch:
git push -f origin cookies-user-tracking

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

Git conflicts in pull requests

I have 2 branches - master and develop
I have been doing some pull requests in my develop branch where it contains 5 items, in which it is the same as the number of items in master.
However, someone did some commits and pushed in a few more items into the master branch, and hence now it has 8 items.
As my pull request in the develop is still not yet approved/merged, whenever I tried to update my pull request, I am getting the message stating that This pull request can't be merged. You will need to resolve conflicts to be able to merge and asked me to do the following:
git fetch origin master
git checkout develop
git merge FETCH_HEAD
git commit
git push origin HEAD
And this happens after I have 'pushed' out my commits, making me confused at times. Then I realized that it is asking me to re-add and re-commit in the additional 3 new items. So does this means I must ensure that the items and contents between these 2 branches of mine should be the same as always? I have always used git pull/fetch but will there be a better way for me to make sure?
What this means is that GitHub would like to merge your PR branch into master, but it can't, because there are conflicts. As you've discussed in the question comments, the best way to deal with this (usually) is to merge your master branch into develop on the command line. That will show you the conflicts and ask you to resolve them. Once you've completed and pushed that merge, the PR will be mergeable back into master using the green button on GitHub.
You could simply merge your deploy branch into master (which I realize sounds a bit more sensible). In that case, you'd be bypassing the PR entirely. You'd have to close the PR "unmerged", and separately you'd manually push the merge commit to master.
By doing it the first way,
you make a better audit trail by merging to master on GitHub, using the PR;
you give your team a chance to review your code after the merge, before it lands on master; and
if you have automatic tests (such as Travis CI or CircleCI) which check PRs, you give them a chance to run your merged code as well.

Git workflow for development on fork

I'm trying to figure out whether I should do my development on my clone of an upstream branch or create a local branch of it first, i.e.
fork upstream
work on my master
issue pull-request against my master
... time passes ...
merge upstream/master into my master
back to 2.
or
fork upstream
branch my master into dev
work on dev
issue pull-request against dev
... time passes ...
merge upstream/master into my master
rebranch master or merge master into dev
back to 2
The reason i consider the second workflow is for scenarios where my pull request isn't accepted or only partially accepted and once i merge upstream i want to make sure that my local is identical to upstream so i don't base future work on a divergent mutation of upstream. Or is there a command when i pull from upstream to master to make my local master identical to it (i.e. discard all local changes?)
When dealing with an upstream repo, I usually do what I think your second workflow suggests. To wit:
I create a branch from upstream's master. If I'm working on a specific feature or bug, I'll name the branch to reflect that; otherwise, I'll call it dev or whatnot.
Work on dev, rebasing from upstream's master as necessary.
Push dev (or whatever I called the branch) and issue my pull request.
Continue pulling upstream's changes down into my master branch.
I.e., I don't do any work on master. This creates a simple, clean branch/pull request for the upstream maintainer.
There's also the very important git rebase that pulls/merges any external changes to the branch you rebase to. That's the way I committed changes to Qt in the past (which is hosted on gitorious which has the great merge request feature). Steps 1 and 2 will probably just be number two for you.
create own clone of "master" on a seperate project
work on the branch currently developed or create a new work branch.
before making the pull request, do a git rebase origin/masteror something similar to make sure your commit applies cleanly to the current master. This has the nice side effect that your changes appear "on top of the stack", ie after all other commits.
Hope this helps you in what you're trying to do.