A Quick Guide To Git, Gerrit, Repo

- Shantanu Goel

The "Repository"

Contains all data and metadata for the git version control system

  • Create new repository
git init
  • "Get" an existing repository
git clone [path-to-repository]

The Three States

git-working-directory-index-head.png

Image © https://git-scm.com/book/

* Staging area is also known as the "index"

Configuration

  • Lots of Configuration options but don't get overwhelmed
  • Just need to setup username and email to be able to commit
git config --global user.name "Shantanu Goel"
git config --global user.email "[email protected]"
  • Look into setting up ssh keys for working easily with remote repositories

Basic workflow

  • Make changes
  • Check if any changes have been made
git status -s
  • Diff the changes to confirm that they are correct
git diff
git diff [filename]
  • Stage the changes (add them to the index)
git add [filename]
# Stage all files under current path
git add .
# See diff of staged files
git diff --cached

Basic workflow continued..

  • Commit the changes (Update the HEAD)
git commit
# Add all tracked files without needing a git add step and
# specify a short commit message with the command itself
git commit -am
  • Check log
git log
git log --oneline --graph

Basic workflow continued..

  • Push changes to remote repository
git push [repository] [branch]
git push origin master 
  • Getting new changes from remote repository
git pull
  • Explore various other switches/options of these commands

Branching and Merging

branches.png

Image © https://atlassian.com/

Branching and Merging

  • Always work on branches while making any non-trivial changes, so that you can develop in isolation.
  • Merge back to master when done
  • Any branch could be "master" branch. Names don't matter
  • List all branches
git branch
  • Switch to an existing branch
git checkout [branch-name]
  • Create new branch and switch to it
git checkout -b [branch-name]

Branching and Merging

  • Merging is the act of combining the commits made in different branches into a unified history
  • Receiving branch: The branch that will have another branch's changes merged into itself
  • You should be on the receiving branch while executing the below command
git merge [branch-to-merge]
  • Deleting a branch (Either changes are merged or not needed anymore otherwise)
git branch -d [branch-name]

Rebasing

Sorry, your browser does not support SVG.

Image © https://atlassian.com/

Rebasing

  • Similar to merge, but rewrites the history
  • Bring in all changes that happened in source branch while you were making changes in your branch.
  • Apply your changes on top of this new base
  • Often required by projects before accepting your patches if they can't be cleanly merged
git rebase
  • Interactive rebase provides you opportunity to pick and choose the commits you need
git rebase -i
  • Don't rebase public/permanent branches

Conflicts

  • You may come across conflicts during merging or rebasing
Unimpacted content
< source-branch
Conflicting code from source branch
========
Conflicting code from feature branch
  • Manually fix the conflicts by editing files
  • Use normal process to add/commit the files
  • For conflicts seen during a rebase, you also have to do either one of:
# Conflicts fixed, continue rebasing
git rebase --continue
# Abort rebasing
git rebase --abort
# Skip this commit
git rebase --skip

Cherry-Picking

  • You may want to pick a specific fix from another branch
  • Or maybe you are jointly working on a feature with someone else maintaining their own feature branch
  • Cherry-picking will take the specified commit and apply it to the head of your branch
git cherry-pick [commit-hash-to-pick]

When things go wrong: Undo

  • When you want to remove your changes temporarily to try something else
# Save current staged and unstaged changes into a hidden location
# and remove them from the working directory
git stash
# Bring back stashed changes
git stash pop
  • Can also be useful while merging/rebasing without committing
  • Can have multiple stashes. Explore through references.

When things go wrong: Undo

  • Temporarily go back to a previous commit in history
git checkout [commit-hash]
  • This will put you in a "Detached head state"
  • You can make changes here but can't commit as you are no longer on a branch

When things go wrong: Undo

  • Discard currently unstaged changes
git checkout -- [file-name-or-path-or.]
  • Remove the changes done in a previous commit
git revert [commit-hash]
  • Creates a new commit which removes the changes introduced by the commit being reverted

When things go wrong: Undo

  • Swiss knife of undoing: git reset
# Reset the head of current branch to given reference
# Move the index as well to this reference
# The changes after the above reference show up as unstaged
# No loss of staged/unstaged changes or other commits
git reset --soft [ref]
# Reset the head of current branch to given reference
# The changes after the above reference show up as staged
# No loss of staged/unstaged changes or other commits
# --mixed is the default mode of reset if you don't specify any option
git reset --mixed [ref]
# Reset the head of current branch to given reference
# All staged/unstaged changes and other commits are removed
# Potential recovery possible (shown in further slides)
# But make sure no unstaged changes present before running this
git reset --hard [ref]

When things go wrong: Undo

  • Git reset visualized

git-reset-tree.jpg

When things go wrong: Undo

  • Recovering from –soft/–mixed reset is easy as there's no data loss from working directory
  • Recovering from –hard is possible as well if the needed changes were committed or staged
  • Check "git reflog" command to see the commits that you want to bring back
  • Check "git fsck" command to find staged changes which were not yet committed but lost due to git reset –hard

Repo

  • Tool developed by Google for large projects working with multiple git repositories
  • Git already has submodules and subtrees but the project may want the repositories to be independently worked on
  • Pros and cons are debatable, largely subjective
  • repo has integration with gerrit, a tool for code reviews and management
  • Not necessary to use repo commands for most things and can use git commands instead

Repo

  • Few main commands that you'll end up using from repo:
# Init repo 
repo init -u url

# Sync all working directories and rebase branches 
repo sync

# Download a specific patch from gerrit
repo download

# Check status of all changes across all projects
repo status

Gerrit

  • Provides web based code review and repository management for git
  • Upload changes to gerrit, following any given guidelines for the project (including code as well as commit messages)
  • Add reviewers and wait for their comments
  • Auto checkers may be integrated by project maintainers for verifying changes
  • -1/-2 from a checker or reviewer needs you to make changes and upload new patches
  • +1 is good, but generally you need a +2 before the changes can be submitted/merged

References

git push –force!