Git Summary: Command and Workflow

Command Comparison

Setting up Repository

  • git init vs. git clone
    • git init is a setup process where you initialize a bare local repo
    • git clone obtain a local development clone repo from an already setup central repository, which can be treated as combining git init and git remote add <name> <url> git

Push vs. Pull

  • git pull vs pull request and git push vs push request
    • git pull pulls the changes from the remote repo to your local repo, which is effectively a git fetch followed by a git merge
    • pull request is you requesting another repo to pull your change (more or less asking them to git pull from your repo). A push request is the other way around, where the target repo ask you to git push your changes

Configuration

  • git config this command allows you to configure your Git configuration on a global or local project level, some common usage includes setting up name and email, configuring text color, or editor choice. There are three configuration levels: --local, --global, --system

    • git --global user.name "John Doh"

    • git --system core.editor vim

    • Note: most config only need to be set once, email is an exception where you will want to use personal email for personal projects and professional email for work-related projects.

Submodule

  • initialize submodule

    git submodule add https://github.com/repo_name <folder_name>

  • update submodule to the latest

    git submodule update --remote --merge

  • reset submodule if you’ve made a modification internally

    git submodule foreach --recursive git reset --hard

  • hard reset the submodule by de-initializing it and re-initializing it

    git submodule deinit -f .

    git submodule update --init

  • remove submodule completely

    git submodule deinit -f <submodule path>

    git rm --force <submodule path>

    rm -rf .git/modules/<submodule path>

Common Workflow

workflow

TLDR:

  • Working directory: where we edit files
  • Staging area: a temporary location where files are kept for the next commit
  • Local repository: contains the code that has been committed
  • Remote repository: the remote server that stores the code

Remote

remote repo stores all branches that are tracked remotely and publicly available, which includes: master (the develop branch), other feature branches (feature1, feature2 and etc)

Local

tracking ref (e.g. origin/master, origin/feature1)

copy of the remote repo you last fetched.

 `git fetch` grabs the *remote repo* and makes a copy of it on your local machine. You never work directly on that copy, because it is used for tracking. When you rebase a branch, it updates your *local branch* with all the latest from that copy you just fetched.

- Usage: `git fetch` updates the latest change from remote (this needs to be combined with `git merge/rebase` to actually affect the working tree)

local branch (e.g. master, feature1)

current branch with all committed changes. So if you have uncommitted changes they are not represented in the local branch above.

- `git status` tracks the change between the *local branch* and *tracking ref*, but it doesn't know the latest corresponding remote branch unless we fetch it.

working tree and index/staging area:

the current state of the files in your current branch. So everything in the branch with your un-committed changes on top of it.

- `git add` and `git commit` to reflect changes onto the *local branch*

Feature Branch Workflow

Get the Latest Production Code:

  • git checkout master switches local branch to master and git status to see if there are local/active changes made in the last session
  • git fetch origin pulls the latest code (of all remote branches in the remote repo like remote master, remote feature1, feature2, etc) from the remote host (e.g. bitbucket). So, you get the most up-to-date code for tracking ref.
  • git rebase origin/develop copy that up-to-date code over to your working tree

Start a Feature Branch:

  • git flow feature start featureName will branch off a new feature branch (e.g. feature3) and check it out (making it your local branch and updating your working tree). So, make sure you have fetched and rebased to the latest before starting. From this point, everything you change is local and isolated on the feature branch.

Save Changes:

  • git add and git commit to updating the local branch with your active change

  • git push origin will push the local branch (e.g. feature3) to the remote version of that branch (note: not the remote master but the remote feature; never push directly to develop) this made the feature branch available for others so they could pull it down to their machine and test it.

    the first time you push a branch to remote repo that doesn’t have it yet, there could be an error saying “no upstream branch”, to fix: git push --set-upstream origin feature/feature3')

  • open up a pull request to merge remote feature to remote master and add reviewers

Update Feature to Match Master:

if you are on a feature branch (e.g. feature3) and you want your branch up-to-date with master because maybe someone has pushed a branch to remote repo that you want the changes from, or addressing a PR comment; you can rebase your branch.

git fetch origin and git rebase origin/develop

  • get the latest in remote repo and rebase your feature branch on top of master, make the adjustments and commit and push. you may get an error while trying to push your branch again. need to use force overwrite.

    commit or stash your active change before rebasing otherwise you might lose it, you’ll be notified for any code conflicts during rebase

  • if your code, on the other hand, is decoupled from anything else, you could just skip the rebase and commit and push.

Update Feature Branch:

  • git checkout feature/branch1
  • git status to see if you have local change by checking it against the current local tracking branch and git fetch origin to update the local tracking branch from remote
  • git rebase origin/feature/branch1: while on feature branch1, rebase local workspace to local tracking branch that was just synced, you now have the latest from remote locally (if there’s local change on the workspace, you need to stash or revert it))