Git Structure
A general organization guide for Git repositories
Git background
A little explanation for people unfamiliar with Git. Git is a version control software that tracks changes in files so that they can be tracked, commented, and combined (merged) together and coordinating distributed developers.
Git tracks changes in "commits" along a history of changes called a "branch".
The first branch that git creates and the one that all history of the project stems from is called "main".
"Branching" refers to creating a new branch from another. When you make a new branch the created branch contains a reference to the whole history of the branch it was created from up to the point it was created.
"Remote" and "Local", are terms used to define where the history is. When you commit a change on your computer it is in the "local" history and when you "push" it is to the remote also called "upstream". Remote is the term for a server that holds a centralized history that other developers can refer to. Remote repositories are also a git repository but not in the environment that you are working in. You can have multiple remote repositories configured for your current local environment. Remote repositories are uniquely named with the default name being "origin".
"Cloning" refers to taking a Remote repository and creating a local copy to work on.
"Checkout" is to take the state of files tracked in the branch at the specified commit and set the tracked filesystem as the representation of those tracked files.
"Merging" is when you add the history of changes from one branch into another. Ultimately all branches trace back to the main branch and merging means adding new changes worked on separately back into the main version of the software.
"Inline merge" is when two people have the same branch checked out then one commits and pushes then the other commits and tries to push. The history is "diverged" meaning that the origin and local history both have a newer commit(s) than the last agreed upon. The person that tries to push last has to pull down the new commit(s) and merge them into the current branch (the same branch) before pushing. This rectifies the history into one "line".
"Conflict" is when git cannot determine the way to order the changes in the history of a file. This happens typically when the same file is changed in separate histories and are changed in vastly different ways.
"Push" and "Pull" refer to syncing commit history between Remote and Local, Push from local to remote and Pull from remote to local.
"Tracked branch" is a remote branch that the local branch is "tracked" against. Typically the names of the local branch and the tracked remote branch are the same but in some cases you can have a local branch tracked against a remote branch of a different name. Typically this happens when multiple remotes are used so you may have local branch A tracked to origin/A and B tracked to other/B.
"Stash" is like a temporary commit that can be used to hold changes in a branch so that you may switch between branches.
Structure
The main branch is
main
and which always represents the latest "stable" version that the general public can access.The
staging
branch (possibly unused in this project) is supposed to represent the next stable version that can be promoted (merged) into main.The
dev
branch is a branch that contains changes (commits and branches) that are merged into it to test that they generally work in the wider implementation of the program. This typically is an "unstable beta" version of the program.Sprint branches are branches that take place of more staging branches and are used to merge a larger collection of changes into before promoting to
staging
/main
. The sprint branch should be named after the next release name likefall-update-sprint
or simplysprint-2
. Sprints are used typically only in large distributed teams that work in parallel on large changes.Branching prefixes, are names that are added before the name of the branch. They should explain what the purpose of the branch is in a single work like "update", "fix", "hotfix", or "feature". When creating a new branch you enter it as part of the branch name in the format
[prefix]/[branch name]
for examplefeature/multiplayer
. Using a/
for prefixing allows most git UIs to show the branches as a folder structure.
The objective is to always work on code in feature or fix branches, merge them into dev for testing, and then merge them into the sprint or staging branch for release later.
Branches should always be created from the top level that "makes sense". If for example you have sprint branches then the branch should typically be made from the sprint branch. The intention is that the branch can be merged into anything which means only ever branching from main
. In this way when you create a branch like feature/new-camera
you can merge it into any branch that needs that new feature but is not yet ready to be promoted to a release branch. And itself can be released individually.
Always keep in mind that branches retain their entire history from when they are branched so creating a branch from main
allows you to make a new branch that wont depend on anything else and wont bring anything with it when it gets promoted to a release branch.
In the situation where you have a branch that was in progress than then needs a new completed fix or feature branch then that branch can be merged directly into the current branch. This means that the current branch will contain the history of that feature branch and this branch. If both branches are published in any order, git can track that the history is already merged.
Bonus points, using CLI
All actions that can be taken with the GitHub desktop app can be performed with the git command line.
The most common actions are checkout, merge, status, add, commit, push and pull.
checkout
This command is used for a lot of changes involving branches and resetting current working files to a commit version.
checkout <branch name>
will literally checkout the branch to that branch at its latest commit.With
-b
flag, these create and checkout.checkout -b <branch name>
will create a new branch from the current branch and commit.checkout -b <branch name> [source branch]
will create a new branch from the source branch at the latest commit in that branch.
merge
merge <branch name>
will merge the history of the named branch into the current branch.with
--no-ff
flag, preserves the history of the merged branch separate from the current branch. This should be the default method of merging.
status
status
, shows a list of changes since the last commit on the current branch.
add
add <path>
, adds (recursively) files that are changed to the staged changes. You can add the current directory.
to add all files and directories from the current directory. If you do this from the root of the project it will add all changes to staged changes.
commit
commit -m <message>
, creates a commit with a new message from the current staged changes.second
-m <message>
, you can add a second message flag with a second message to add a description to the commit message if more detail is needed. Git always supports this but not all UIs show this data.
push
push
, sends the local history of the current branch to the remote tracked branch.with
-u
flagpush -u [remote name] [branch name]
, will push and track the current branch as tracked to a branch on a specified remote with the specified remote branch name
pull
pull
, gets the remote history of the current tracked branch and checks out the current branch to the latest commit of the remote.If you are checking out to a branch that was not created by you or has not been worked on by you recently it is a good idea to pull before creating new changes to add to avoid inline merges.
branch
branch -a
, will list all the branches local and remote (local first) for the repository.branch -m <old name> <new name>
, m for "move" will rename a branch from the old name to the new namebranch -d <name>
, will delete the local specified branch
remote
remote add <name> <location>
, will add a named remote that points to a location.remote set-url <name> <location>
, will update the named remote to a new location.remote -v
, will list all remotes currently configured.It's worth noting that there are many forms of remotes. The location can represent a literal path to say a network or removable drive or to a internet connected resource like GitHub Gitlab or even an FTP filesystem.
Last updated