- Understanding Brancing, Forking, Pull Requests, and Merging
- Understanding the differences between working alone and in a team
- Proper procedures to set to ensure good code is kept, and bad code is not
- The biggest golden rule: The
master
branch is always deployable and ready to go - A deployable master branch is important for many reasons. First, it enables anyone new to a project to pull and build immediately without errors. Nothing is so frustrating as not being able to build an unfamiliar project.
- A deployable master is a safety net. If master is always deployable, then we can deploy without worry.
- And lastly, because we are using Heroku and Heroku uses the master branch for what is deployed, we need to always be sure master works
Within a collaborative project, while working on your Git Team Workflow, there are two roles you can fulfill: programmer and manager.
Any given member of the project may be a programmer or a manager at any moment! Programmers implement features, while managers integrate the work of the members of the team into the application.
- In your projects, you will have to assign someone the title of manager that not only writes code, but also manages the project
- This includes things like setting deadlines and merging code.
- The manager also creates the repo, and invites everyone to it
Manager:
- Create a repo locally, using
git init
. - Create a remote version of this repo on GitHub (using
hub create
if you wish). - Ensure you have a remote "link" to the GitHub repo, either by using
git remote add
orgit remote rename
: the remote should be calledupstream
.
Programmer:
- Identify the repo created by your manager on GitHub.
- Fork the repo to your own account.
- Use
git clone
to copy your account's repo locally. Use the SSH URL when cloning if possible, and name the remoteorigin
. The command should look likegit clone git@github.com:<yourname>/<repo_name>
. - Use
git remote add
to add a link to the manager's repo as well! This remote should be calledupstream
, and should be the SSH URL.
When you are complete, your setups should be in the form:
Manager & Programmer:
- Make sure you have created the repo using the create repo workflow.
- Ensure you are on the
master
branch withgit checkout
. Only pull when you are onmaster
. - Update your local codebase with
git pull upstream master
. You should never have a merge conflict. If you do, stop, because something is wrong. - Use a feature branch with
git checkout <feature_branch_name>
; add-b
to create a new branch if necessary. - Write some code!
- When you have completed a feature, submit your work.
- Managers: skip to accepting and merging work, step #4.
- Programmers: push the branch to
origin <feature_branch_name>
.
- On GitHub, submit a pull request (PR) from your feature branch,
where the
base
is the manager's master branch (upstream/master
) and thehead
is your origin's feature branch. - Go back to step #2.
Manager & Programmer:
- Make changes to your files.
- Stage a series of changes that go together using
git add
. Try not to usegit add -A
: be thoughtful about what you are adding! - Take a snapshot of those changes with a meaningful description using
git commit
. Make small commits, and often!
Manager:
- Find pull request (PR) submitted on GitHub and check it:
- if the request is very small and simple, you may merge it online;
- if the request is not well-commented and obvious as to its purpose, you should ask for further explanation in the PR;
- if the request is too large, poorly written or stylistically problematic, or how to test it afterwards is unclear, close the PR with a clear explanation, asking the programmer to resubmit later;
- otherwise:
- Use
git checkout master && git pull upstream master
to ensure your local master branch has the most updated version of the codebase. If you are working on a feature branch you may need togit commit
orgit stash
your work. - Follow the command line instructions from GitHub's PR Merge page
or, even better, from their documentation:
git fetch origin pull/<pr_id>/head:<feature_branch>
to fetch the changes;git checkout <feature_branch>
to go to the code;
- Use
git merge master
in the feature branch to merge the current codebase in to it. - Fix any merge conflicts that arise! Use
git status
liberally to identify these. If there were any, be sure to usegit add
andgit commit -m "merge"
to commit the fixes. - Test the new feature! Do not push up the feature if it is not
working!
- If the tests fail, close the PR with a clear explanation, asking the programmer to resubmit with fixes.
- If you are unsure of the outcome of the tests, you should ask for further explanation in the PR before going forward.
- Accept and share the changes using
git push upstream master
(the only time you ever push toupstream/master
).
![Diagram showing the team workflow.][….png]
$ git init
Initializes a new local repository and begins version tracking. Creates a hidden directory that tracks info about the repository, including remote repositories.$ git clone <ssh_or_http_url>
Clones a remote repository as a new local repository with the given connection format (SSH or HTTPS).$ git remote add <remote_name> <ssh_or_http_url>
Connects your repo to a new remote at the given URL, via the given connection format (SSH or HTTPS), and names it with the given name.
$ git branch <branch_name>
Creates a new branch with the given name.$ git checkout <branch_name>
Moves you to the branch (or commit in history) with the given name.$ git checkout - b <branch_name>
Creates a new branch and checks it out, all in one!$ git merge <branch_name>
Merges the branch cwith the given name into the current branch.
$ git add <file_name>
Adds changes made to the given file to the staging area.$ git add .
Adds all changes (creating, updating and removing files), to files in this directory and sub-directories, to the staging area.$ git add -A
Adds all changes (creating, updating and removing files), in all files, to the staging area.$ git add -p
Adds updates in all staged files to the staging area, but runs you through all the changes step by step.
$ git commit -m "awesome commit message"
Saves a snapshot of the filesystem including any changes that have been added/staged as a commit. It saves the commit with a simple description, or message, given after-m
.$ git commit
Commits as above, but takes you to a text editor (nano
) to edit the commit's message.
$ git status
Prints out the current "tracking state" of the repo. The state includes information about changes, additions and deletions of files, whether or not these changes have been added/stages, and sometimes even any merge conflicts.$ git log
Prints out the commit history of the current branch of the current repo.$ git branch
&$ git branch -v
Prints out a list of all available branches in the repo.$ git remote
&$ git remote -v
Prints out a list of all available bremotes connected to the repo.$ git diff <branch_or_commit_name>
Prints out information about differences, as insertions (in green) and deletions (in red), between the current commit and the given commit (or the most current commit in the given branch).
$ git push (-u) (<remote_name> <branch_name>)
Push, or send, commits to remote at the given branch.-u
saves the remote and branch names as default for future use.$ git fetch <remote_name> <branch_name>
Fetch, or receive, commits from a given remote at the given branch. Stores these commits in either the named commit, or in a special, new branch.$ git pull <remote_name> <branch_name>
Performs agit fetch
into a new branch, then merges it into the current branch and removes the fetched branch.
- the workflow that we will encourage you to use is one called the
feature branch
workflow. - what it means is in every team, you only code on things called
feature branches
, and the only thing that touches master is everyone's merged in code - this simple workflow has a couple core components
master
is always production-like and deployable.rebase
during feature development, explicit (non fast-forward) merge when done.
- Everyone on the team starts with a clean slate, that is a fresh repo. you start by cloning into it and getting it in your local environment
- From now on, you will only write code in a seperate branch called a
feature branch
git checkout -b <feature-branch-name>
- write code, make feature, fix bugs
- feature branch names should be short, descriptive (to what this branch is doing), and made from a working version of master
- Once that branch has been completed, and you're ready to move on, you now push that branch to github using the feature branch syntax
git push origin <feature-branch-name>
- From there the project lead (whoever is hosting that repo) should get an email about a push, and they (or someone else) should review the code. You will see an image like this
- that person will make a pull request
- Then, the lead (or anyone else beside the person who just pushed) will review the code.
- that person will then merge the pull request if everything is satisfactory
- Now, once code has been merged into master, everyone needs to update their branches to reflect the changes
- make sure you are always in master before doing this
git checkout master
- now run
git pull origin master
- if your code is affected by the merge (i.e. something you are working on has touched what someone else is working on), you should run a rebase:
git fetch origin && git rebase origin/master
inside your feature branch - what is a
rebase
? Rebasing lets us move branches around by changing the commit that they are based on. Conceptually, this is what it allows us to do:
- Have one person work on one thing at a time. Be very specific about what people are working on and don't go into those files. That is how merge conflicts happen
- Never merge your own pull requests. Just like getting someone to proof-read an essay you've written, you need someone to look over what you have done before it gets into master
Articles and tutorials on branching and workflows in Git:
- Git Branching
- Common Git Workflows
- Merging vs Rebasing Workflows ('Conceptual Overiew' section)
- In-depth Discussion of a Workflow
- 'Reset Demystified' (helps to understand the structures of Git)
- A Git Branching visualization game!