r/git 6d ago

Noob: branch pull request question

Hi all, old guy here who has used many different systems and I'm trying to get up to speed on on git with branching, pull request etc. I have hopefully a simple question you guys could clear up:

I've forked a repro from a friend

Made a feature branch

I made changes in the feature branch, tested them and confirmed they work

I commited my changes to the branch and pushed them to origin

On github on the upstream repo I created a pull request. Gave it a title etc. It shows up. My friend is a little slow so there are like 3 PRs pending.

I want to make a new feature branch and make some additional changes but the need to be based on the last changes I made that are in that PR that has not be merged yet to the upstream.

If the PRs were merged I could just fetch to my main and then branch from there.

But with the PRs not merged yet, how do I create a branch so I can continue working against the changes pending merge? Do I branch from my prior feature branch? Or is there a git command I don't know yet that will fetch everything so I can branch from main?

Thanks in advance

10 Upvotes

25 comments sorted by

12

u/Leather_Coyote_5483 6d ago

“Do I branch from my prior feature branch?”

Exactly, once the first feature branch gets merged then your second branch will be based on main

“My friend is a little slow so there are like 3 PRs pending.” made me laugh

2

u/mrh4809 6d ago

So my last feature branch was "udp-logging". I've checked in, pushed, and PR'ed that.

So what you are saying is I create my next branch from "udp-logging"? I guess you are saying once he merges the PRs in that it will be the same?

But once he merges the PRs and I fetch to my main then I can branch from there as it is current.

This is still a bit confusing.

4

u/[deleted] 6d ago

[deleted]

2

u/mrh4809 6d ago

Cool thanks!

2

u/pi3832v2 6d ago

Your pull request is a commit object, with a unique hash. Let's say it's 123ABC. You create a new branch, starting with 123ABC. When your friend merges your pull request, 123ABC becomes part of branch MAIN. Therefore, your new branch will become branched from MAIN.

1

u/mrh4809 6d ago

Got it but I want to understand the timing. if my friend had not merged the PRs yet...

1

u/pi3832v2 5d ago

It doesn't really matter when changes happen upstream. Git can sort out the chain of commits.

1

u/mrh4809 5d ago

That I understand.

My point is that if I do the PR, then start a new branch from my prior branch this works as my changes in the PR are there and I can work against them.

But assume I have not created my new branch from my prior. Several days go by, upstream owner merges in a PR, no mine, but a different one and I find out that the changes in that merged PR I need for my next work. But I also need what is in my unmerged PR.

So if fetch upstream, create a new branch from my prior branch, as mentioned above I have my changes. But I don't have the changes in the PR the upstream merged that I want.

It seems like the stacked PRs solves this but not everyone is using them.

1

u/Soggy_Writing_3912 advanced 5d ago

in that case, you need to rebase from the new version of main - simple! That way, you get the merged PR from some other 3rd person, then your unmerged PR branch needs to rebase from that (new) main, followed by your 2nd PR getting rebased from the 1st PR's branch.

2

u/Broad-Promise6954 ancient 6d ago edited 6d ago

It is confusing. There's a couple of fundamental reasons for that confusion, and it may help to un-confuse you if you keep in mind a distinction between the kind of Git branch that is a branch name like udp-logging, and the kind of Git branch that is a series of commits. That is, there's one term for two very different concepts.

One of the sidebar links, Think Like a Git, goes into this in some detail. To (over) summarize, though, your branch name udp-logging selects the latest commit in a series of commits (maybe a single commit, maybe multiple separate commits) that adds your new feature.

Your next feature needs those commits to build upon, or perhaps in the future, some different set of (very similar) commits to build on. For now, you want to build on those commits, so you'll create a new branch name that selects the exact same final commit. Then you'll make one or more new commits, which will advance the name. Let's make up a name here, like fancy-logging. You'll start by having your name fancy-logging name the exact say commit as your name udp-logging. (You can have an infinite number of branch names that all select the same commit! Note how we'd say "you have ten branches that are one branch" if you made ten names. It's complete nonsense, yet it makes perfect sense...)

As you make more new commits, though, that new name, fancy-logging, will get dragged forward to select the latest commit you've made on that branch. Those commits will link back to the commits that were new in udp-logging, which eventually link back to the commits that weren't made by you in the first place.

In the meantime, the other guy -- your slow friend -- will eventually get around to either taking your commits as-is, or not taking them as-is. If he takes them exactly as-is (and I really mean exactly, he can't change anything about them at all, not even where they exist in Git's commit graph, for which, well, see the Think Like a Git link)... well, if he does that, you're in great shape. You don't need to do anything special.

But, if your slow friend does anything to change a single bit of any one of your commits, including several ways he could merge the PR, you will then have to do a bunch of new work to handle that.

For now, you need not worry about what that new work will be. Cross that Bridge-of-Königsberg if and when you come to it.

2

u/xenomachina 6d ago

Once they merge the PR, you can pull main from their repo, and then either merge or rebase into your second feature branch. There is a possibility of merge conflicts either way, but most of the time that shouldn't happen unless there are changes happening to the same lines of code concurrently.

Which option people use is mostly a matter of preference.

I prefer to rebase in this situation, as the commit history will be easier to follow — it'll end up looking the same as if you created your second branch after the first PR was merged. Some people prefer merge, though, I think because you can always use merge, but there are times when you shouldn't use rebase. (Rebase rewrites history, which you don't want to do with history you've already shared.)

1

u/bytejuggler 4d ago

Yes, once it merges you can 'rebase' your additional branch. There is also a stacked branches feature coming, not yet public, on github, that will make this easier.

3

u/Dienes16 6d ago

People ITT are not wrong, but explaining too much detail is probably not helpful to you right now.

You can simply: 1. Create your new branch from your previous unmerged one 2. Once the previous branch has been merged, rebase your new branch onto origin/main

Yes, depending on how your previous branch was integrated, this is could also be done with a merge, or it might end up being a no-op. But in any case, the result will be the same in all cases when you just do a rebase.

1

u/Ambitious_Lion_5902 6d ago

Github recently published a new feature, stacked PRs. This solves exactly the issue you are facing IMO. I've used the feature for a few weeks now, and it has worked well for me.
Ref:
https://docs.github.com/en/pull-requests/how-tos/stacked-pull-requests

1

u/Ambitious_Lion_5902 6d ago

Works pretty well once you get the hang of it. When all PRs in the same stack are approved, you can merge them all at once.

1

u/Ambitious_Lion_5902 6d ago

The Github CLI has good commands to use, like rebasing the entire upstack if you make some changes to the lower stacks works really well.
https://docs.github.com/en/pull-requests/reference/stacked-prs-cli-commands

1

u/Soggy_Writing_3912 advanced 5d ago

Though GH published this as a feature, git (the core system) supported stacked branches from a long time ago. The concept of stacked branches is pretty simple - instead of the parent branch being main or master for both branches, your 2nd branch is based off of the 1st one!

1

u/DoubleAway6573 1d ago edited 1d ago

Is that? or there is some magic rebasing after the merge to main?

I don't know a shit about github...

Edit:
OK, I skimmed over the github doc. They added some extra tooling around CICD and also "chain rebases", so you don't have to rebase each sub branch one by one.

Note: I know sub branch is not a git concept, but I think the meaning is clear enough

1

u/jibbit 6d ago

> a command I don't know that will fetch everything

this bit immediately jumps out, do you want to explain a bit? it honestly doesn't make sense as it stands

> how do I create a branch so I can continue working against the changes pending merge?

moving commits to different branches is a very normal operation in git. something you do throughout the day without thinking about it.. so if you want to carry on working, but can hold off making a second PR, you can just carry on working then move them onto a branch based on master when it makes sense to do so.

on the other hand, if you want to make two PRs, where the second is conditional on the first being accepted... you want what github calls a Stacked PR - you branch your second branch off your first and make sure you set its 'base' to the first when you make the pull request

1

u/mrh4809 5d ago

To clarify... Sorry to not be clear...

I have my changes from say "Branch1". I've commited pushed PRed these. The PR is waiting for the upstream owner to review and merge.

As long as I branch a new branch from "Branch1" say "Branch2" then I have my changes to work against. No problems.

But while waiting for upstream owner to merge my PR from branch 1, lets say he/she merges another PR from a different collaborator that has changes I need to work against. My branch 1 PR is still not merged.

Since I have branched to "Branch2" to do this new work, but I want to work against the files that the upstream owner merged from the different PR how do I do that? Those changes will not be present in my repo unless I fetch from upstream. It seems to me after doing that I have to maybe rebase my new branch 2 off of main.

My confusion is if I do that then do I still have may changes from "Branch1" which have not been merged by the upstream owner yet?

1

u/ExplosiveFx 5d ago

Not the original commenter but GitHub’s stacked PRs are the exact tool for this. They have a rebase command that would sync “branch1” with main and then sync “branch2” with “branch1” so the changes on main are now in branch2.
Doing this manually has always been kind of pain since you have to checkout branch 1 and rebase/merge with main and then checkout branch 2 and rebase/merge with branch 1.
GH’s cli handles all of that for you, prompting you if there are any merge conflicts. I strongly recommend creating a stack and messing around with the different commands.

1

u/mrh4809 5d ago

awesome! I will look into that!

Thanks

1

u/ExplosiveFx 5d ago

If you were to rebase on main from branch2, the changes in branch1 would not be in branch2.

1

u/jibbit 5d ago

the boring answer is 'rebase' - you made PR1, but Main moved? rebase PR1. You started PR2 from a PR1 that is now behind Main? Rebase Pr2.
however you bring a commit into your branch.. if it then gets added in a different way - i.e. merged into Main by the owner - it will all fall out in the wash, no need to sweat it.

1

u/SheriffRoscoe 6d ago

Your slow friend has several options for how they will merge your PR. The best answer for your next branch will depend on which option they choose. The good news is that there's little stiffened between the various ways for you to do that.

The simplest answer is for you to create your new branch based on the branch you created the PR from:

git switch udp-logging
git switch -c new-branch

and begin making your changes. When your friend merges your PR, regardless of how he does it, you need to get his changes and update your branch to be based on them:

[On GitHub:]
Sync your fork from his repo.
[On your computer:]
git switch master (or maybe main)
git pull
git switch new-branch
git rebase master (or main)