On Tue, Jan 14, 2020 at 12:12 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> On 14/01/20 10:07 -0600, Peter Bergner wrote: > >As somewhat of a git newbie and given gcc developers will do a git push of > >our changes rather than employing a git pull development model, I'd like > >a little hand holding on what my new gcc git workflow should be, so I > don't > >screw up the upstream repo by pushing something to the wrong place. :-) > > > >I know enough that I should be using local branches to develop my changes, > >so I want something like: > > > > git checkout master > > git pull > > git checkout -b <branchNameHere> > > <modify and add new files> > > git commit -m "My commit message1" > > <modify and add new files> > > git commit -m "My commit message2" > > <modify and add new files> > > git commit -m "My commit message3" > > <all done!> > > > >At this point, I get a little confused. :-) I know to submit my patch > >for review, I'll want to squash my commits down into one patch, but how > >does one do that? > > This is Git, there are a hundred ways ;-) > > > >Should I do that now or only when I'm ready to > >push this change to the upstream repo or ??? > > Totally up to you. You might want to squash some commits early, e.g. > to fix silly typos, but keep most of the branch history intact until > the last minute (to help you remember what you changed and why). > That's my preference. > > >Do I need to even do that? > > If it's a long-lived feature branch you might want to keep the > separate commits and merge them all to master preserving the branch > history (don't take my word for it, I can't remember what we decided > should be the policy for such long-lived branches). > I think we're prohibiting merges to master. We definitely don't want merges of branches with commits that don't each satisfy the normal rules for commits. If it's just a short-lived branch to change one thing, or fix one bug, > then what you push should be a single, self-contained commit (even if > you happened to develop it as a series of mini-commits locally). > > >Also, when I'm ready to push this "change" upstream to trunk, I'll need > >to move this over to my master and then push. > > Strictly speaking, you don't need to. You can push that branch > directly to master: git push origin HEAD:master > That will fail unless the current branch is up-to-date with master, > but would work fine if you've already rebased your branch on master, > or if master hasn't moved since you branched. > > >What are the recommended > >commands for doing that? I assume I need to rebase my branch to > >current upstream master, since that probably has moved forward since > >I checked my code out. > > You can either rebase on the new master (i.e. bring the new stuff from > master into your branch) or the other way around (bring the stuff from > your branch into master). > > A pretty straightforward way to do the second way is: > > git checkout master > git pull > git merge --squash <branchNameHere> > [resolve any merge conflicts] > [build + test again if your branch was behind master] > git push > > i.e. pull the changes from your branch onto master, then push. > > This leaves your <branchNameHere> branch untouched, so you still have > all the history locally for future reference. > > There are other ways e.g. 'git rebase --interactive master' and > squash all the commits in the branch that way. Interactive rebases are > awesome, and very useful. It's a fairly manual process, but that gives > you full control. Get familiar with it. > > Or, to (non-interactively) rebase your branch on master (which you > might want to do periodically anyway, before you're ready to push > upstream): > > git checkout master > git pull > git checkout <branchNameHere> > git rebase master > [resolve any merge conflicts] > [build + test] > > That's rebased your branch, but not actually squashed the branch > commits yet. You can do that by checking out master and doing a > merge --squash (as above) or just on the branch: > > # make this branch's committed state (aka "index") the same as master > git reset master > # but that didn't touch the content of the working directory, > # that still matches your branch, so you can add+commit all the > # files in the working dir that differ from the "index": > git add --all > git commit > If you use git reset --soft you don't need to add again. I use this alias all the time to combine commits: sq = "!f(){ git reset --soft ${@:-HEAD^} && git commit --amend -C HEAD; }; f" this combines all the commits since into the argument commit (or the penultimate commit, if not specifie). > This alters your branch's history to be a single commit against > master, which contains all the changes that you'd done on the branch. > I've never used this method, so I hesitate to recommend it. It's the > least obvious way IMO. > > And after either of the rebase methods, you still need to get that > single commit onto master to push (unless you're going to push > directly from the branch). So that might be a reason to prefer doing a > "merge --squash" to squash at the same time as pulling the changes > into master (i.e. the first method above). > > >Also, at what point do I write my final commit message, which is different > >than the (possibly simple) commit messages above? Is that done after I've > >pulled my local branch into my master? ...or before? ...or during the > >merge over? > > Doesn't matter. As long as you push a single commit with a good commit > message, it doesn't matter when that was written. Personally I think > doing it at the end when you do the merge --squash to add a single > commit to master. > > >...and this is just for changes going to trunk. How does all this change > >when I want to push changes to a release or vendor branch? > > It's pretty similar. Create a branch from the release branch, merge it > back to the release branch. > > Personally, I don't usually use branches for backports, because I only > have one in flight at a time. So I'll just make the change directly in > the release branch and push it directly from there. I rarely have > changes for the release branches that require a series of local > commits that warrant their own branch. I go from making the changes to > pushing it in an hour or two, and since I'm not doing anything else on > that release branch I don't need to use separate branches to keep my > work isolated until it's ready. > > > >I guess I'm just looking for some simple workflow commands for both > >trunk and release/vendor branches I can follow until I'm a little more > >confident in my git knowledge. > > > >I'm guessing I'm not the only one who would like this info, so maybe > >someone can add this to our wiki? > > Yes but it takes time :-) > >