-
Notifications
You must be signed in to change notification settings - Fork 2
Git Workflow
I don't like git UI's, not because I'm fundamentally against them, but because they tend to be opinionated and muck around with names of things.
For example, some UI's use the word "sync" to indicate some kind of bi-directional synchronization between the server and the client.
This doesn't exist in git.
It's not a thing.
If you try and find a command for sync
, you won't be able to.
main
is our primary branch where our latest code lives.
It is intended to be buildable at all times.
Introducing a build break to main
is bad.
Don't do it.
Git is really complicated because, for it's primary use case, it needs to be. It was invented to help manage source of Linux distributions where N number of different entities were all working on N different versions of Linux at the same time. Each git repo is considered a master repository for some set of developers (Redhat, Ubuntu, Arch, etc.) and they need some way to share changes somewhat sanely.
We do not work this way at all. In our system, we have only 1 set of developers. All of the complexity is wasted on us.
As mentioned above, main
is our primary branch.
It's not important as a local branch because you would never do work in it directly.
Unfortunately, a lot of tutorials spend a lot of energy managing your local version of main relative to the server's version of main.
Don't waste effort doing this.
Nearly all commands that work off of branches also work off of a remote branch, in our case... origin/main
.
An example of this:
git checkout --track -b my_branch origin/main
That creates a new branch called my_branch
and sets the upstream of that branch to origin/main
.
Note, because we did that, when we pull changes into our branch, we don't need to first check out the local main, pull the changes from origin/main
into the local main, then checkout our branch again and pull from there... We bypass that entirely.
All you need to do is:
git pull --rebase origin
Also, because of how the pull requests work are implemented, unless you have conflicts you need to resolve, you rarely need to pull changes into your branch before pushing to the server. The server will be appending your changes to the existing code, so as long as it can resolve it, it will happily do that even if your code is slightly out of date.
Before you start working on something new, it's best to make sure you have the latest code on your machine.
You can do this by doing git fetch
to update your git repository.
Alternatively, if you are in your local main, you can do a git pull
because that will implicitly do the git fetch
as well.
Each branch can be considered a unit of work which will be integrated. Your personal branches are used once. After you push the changes to the server and complete the pull request, you will delete your local branch. NOT deleting and attempting to reuse a previously merged branch will only give you headaches. Don't do it. Use the branch once.
- Create branch
- Do your work and commit
- Push your work
- Pull request to main
- Delete your local branch
- Go to 1
Name your branch with your name in it, a forward slash (so that git UI's will format them nicely), and a short name so that you (and others) can vaguely identify what types of changes it contains (not critical).
darkscott/updating_ui
darkscott/buildfix
darkscott_foo
xxx
Create your branch by either using the full command, or the alias from below.
git checkout --track -b darkscott/buildfix origin/main
... or ...
git nb darkscott/buildfix
You are now free to make your changes.
To commit your code, first you need to stage
your code that you wish to be committed.
This allows you to selectively pick what code will be pushed, and what code will not.
Note: It is best practice to NOT do git add .
to add all files. You probably will anyway, but it sucks when you add something you didn't intend to.
Check what is staged by doing git status
Once the code you want has been staged, commit the code by doing git commit -m "Your message describing the code"
.
You can do this often, even if you don't intend to push just yet.
You can always squash commit when you complete the the pull request.
When you push your code, you are taking your local branch and creating a copy of that history on the server. Your local branch still exists, and you can make further changes and push again. The command to push to your remote branch is
git push origin HEAD
... or if using the alias ...
git pushx
Note 1: You can use this as a quick backup of your work to the server...like in case your computer crashes or something... Pushing does not create a pull request, it's just a copy of your local branch.
Note 2: If you push to the server and then do something which changes your history on your local version, such as rebasing changes from origin/main, you will need to force push your next update to the remote branch because the histories will not match. git push origin HEAD --force
or git pushx --force
After pushing your code and you want to bring that code into main, go to the github repo and create a pull request for it. Before creating the review, check the diffs to make sure that you are happy with them. When you create the review, people will comment and maybe ask you to make changes. Making changes is easy and does NOT require you to make a new branch or anything. Simply resume editing the code on your local machine that are asked in the review, stage and commit the changes, and push again. The code review will automatically be updated with your latest code after you push.
Once the pull request is ready to be completed, you have two options for how to merge them: rebase
and squash
When given an option, delete the branch on the server as part of the pull request completing, as it is not needed anymore.
Rebase takes all of your changes (however many commits you have) and appends them to the end of the current tree. This is useful if you have only 1 commit, or a few commits which are nicely blocked with good commit messages (e.g. NOT "WIP1" "WIP2" "OOPS WIP").
Squash commit is great if you have lots of tiny commits (you follow the mantra of 'commit early, commit often') and you don't want the individual history, just the final result.
If you only have 1 commit in your change history, they are effectively the same thing.
- Fetch the latest from the server
- Create a new branch tracking origin/main
- Delete your old local branch
Because git's command lines can be overwhelmingly verbose to type out, I have created some aliases that I use to make things easier. I recommend doing the commands manually for a little bit, at least, just so these don't act as magic. Once they are no longer magic, you're free to use these or rename them as you like.
unstage: Removes all items previously staged with "git add"
nb: Creates and checks out a new branch which tracks the main branch of origin
undo: Removes the most recent commit (in case you committed before you were ready)
last: Shows the information about the most recent commit
pushx: Pushes the current branch to origin, creating the branch on origin if it doesn't exist there yet
pullr: My favorite, pulls changes from origin and rebases your current branch from it, using the merge options that do a good job of resolving common conflicts.
Usage: `git pullr origin/main`
git config --global --edit
[alias]
unstage = reset HEAD --
nb = checkout --track origin/main -b
undo = reset --soft HEAD^
last = log -1 HEAD
pushx = push origin HEAD
pullr = pull --rebase -s recursive -Xpatience -Xignore-all-space -Xrenormalize origin