Simple Git¶
Overview¶
Git (install) is a version control system found everywhere in software development. It is often used from the command line.
Software often lives in multiple versions at once. At least one stable version and a version for each new feature or bug fix.
Versions are also called branches. Changes to branches are saved as commits, which are like checkpoints, and the entire project folder is a repository/repo. Repos on your computer are local. Repos living on github are remote. The initial (and usually main) branch of a repo is often called master.
Git allows us to:
- make a local copy of a remote repo
- sync the local repo with the remote repo
- merge branches
- create new branches from existing branches
- switch quickly between branches
- store branches together in one folder
- view commit history
- compare two commits
Git repositories are most often uploaded to Github where they can be public or private.
Github is a place where a lot of software is hosted. Many developers make their source code publicly visible, which allows anybody to write edits and requests for their edits to be accepted, which are called pull requests.
Basic usage¶
Create a repo¶
Create your new repository on github.
Make a local copy of a github repo¶
Find the address to clone here.
Then do:
$ git clone git@github.com:siowyisheng/simple-software-development.git
A folder will then be created in the folder where you did the command.
Check the status of your local repo¶
$ git status
This shows useful information, including changes which have not been added and changes which have not been committed, as well as the status of the commits of the local repo versus the commits of the local copy of the remote repo.
Make a commit¶
First, we add the files that we want to commit:
# this adds all changed files
$ git add .
# this adds one changed file
$ git add my_file.py
# this adds all changed files within a folder
$ git add my_folder
Then:
$ git commit -m 'feat: adds commenting feature'
Note
The part within the quotes is the commit message, which is important for logging. One best practice is to use semantic commits.
For a longer commit message:
$ git commit
This brings you to a text editor within your shell to input
your commit message. End the commit message with esc, Z, Z
.
Push local changes to a remote repo¶
To update the remote repo with your local commits:
$ git push
This could fail if the remote repo has extra commits compared to your local repo, which could be caused by (A) your teammates pushing changes, or (B) if you intentionally removed some commits on your local repo.
In situation (A), we need to pull the changes from remote.
In situation (B), we can use:
$ git push --force-with-lease
Warning
It could also fail if you don’t have push permission, in which case you should make a pull request.
Pull changes from remote¶
To update the local repo with changes from the remote:
$ git pull
You may need to resolve merge conflicts.
Create a branch¶
To create a new branch, first switch to the branch that you want base off of, then:
$ git checkout -b my_branch_name
Switch to a branch¶
$ git checkout my_target_branch
Resolve merge conflicts¶
Merge conflicts can happen when updating the local repo, either
through git pull
or git stash pop
. This happens when
multiple commits touch the same lines of code and git does not
know which commit to follow.
When git notifies you of a merge conflict, you can open the file with the merge conflict in vscode and look for something like:
<<<<<<< Updated upstream
some code edited to A
=======
some code edited to B
>>>>>>> Stashed/Incoming changes
Then analyse the code and delete the unwanted code. Back in the command line:
$ git add file_with_merge_conflict
Compare two commits¶
git diff base_commit_reference new_commit_reference
A commit reference can be:
- a partial commit hash like
1fc2cd7
, which you can find from the commit history, HEAD
, which is a reference to the last commit in the current branch- a branch name like
master
, which points to the latest commit in that branch
Note
A commit ref can also have a suffix like ~1
, which means 1 commit before that commit.
Example to compare the second last commit with the latest commit:
$ git diff HEAD~1 HEAD
More usage¶
TODO:
Best practices¶
Make focused commits and include the commit type in the commit message:
feat: adds some new feature
fix: fixes some bug
content: changes some values/strings/content only (no actual code change)
test: adds tests
refactor: refactors some section
docs: changes some documentation
chore: updates build (no code change)
perf: improves performance of some section (by refactoring)
style: formats some section
## How do remotes repositories work?
A remote repository first exists at a remote location; often, a github repo. When you git clone the repo, you create a local copy of the repo and the branches which track the remote repo’s branches. You also create a reference to the remote repo and its branches.
## What is the difference between git fetch and git pull?
git fetch accesses the remote repo and updates your reference to the remote repo. git pull does a git fetch and also does a git merge to merge your reference to the remote branch with your local copy of the remote branch.
See [above](#how-do-remotes-repositories-work) to understand how remote repositories work.
## What are some common commands?
git diff HEAD~1 HEAD - View differences between this commit and the previous.
## How do I track the history of a file?
gitk (filename) or git log -p (filename).
## How do I overwrite the remote after making a mistake?
git push –force
## How do I reset my local branch to copy the remote?
git reset –hard origin/(your_branch_name)
## How do I find a commit by the message?
git log –all –grep=’your search string’
## How do I delete a local branch?
git branch -D branch_name
## How do I remove references to branches on the remote?
git fetch –prune
## How do I move recent commits to a new branch?
Scenario: You made 5 commits to master although you were supposed to work on a new branch.
`bash
git branch newbranch
git reset --hard HEAD~5
git checkout newbranch
`
## How do I check which files were edited between two commits?
git diff –name-only HEAD~1 HEAD
## How do I stash just one or a few files?
`bash
git stash save -p
`
From there, use:
- a to add the file to the stash
- d to ignore the file
- q to ignore the rest of the files
## How do I see changes of all recent commits?
`bash
git log -p
`
## How do I see an overview of what recent commits touched?
`bash
git log --stat
`
## How do I amend my last commit message?
`bash
git commit --amend
`
## How do I add a file to a commit?
`bash
git commit -m 'initial commit'
git add forgotten_file
git commit --amend
`
## How do I find all commits that added or removed a certain string?
`bash
git log -S "dude, where's my car?" --source --all
git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all
`
## How do I list all files which were changed between two commits?
`bash
git log --name-only --pretty=oneline --full-index 0be8c001..HEAD | grep -vE '^[0-9a-f]{40} ' | sort | uniq
`
## How do I checkout just one file from a previous commit?
`bash
git checkout c5f567 -- file1/to/restore
`
git blame