207 lines
7.8 KiB
Markdown
207 lines
7.8 KiB
Markdown
|
## Quick start
|
||
|
Git is an indispensable tool for code development, though in reality you'll only
|
||
|
use a few commands on a day to day basis. This section provides a quick overview
|
||
|
of those commands
|
||
|
```
|
||
|
$ git fetch
|
||
|
$ git status -s
|
||
|
$ git diff file_1
|
||
|
$ git add some_dir
|
||
|
$ git commit -m "Changed some directory"
|
||
|
$ git switch -c new_branch
|
||
|
$ git restore file_2
|
||
|
$ git commit -a
|
||
|
$ git log --graph --all --oneline --decorate | less
|
||
|
$ git push
|
||
|
```
|
||
|
The above represent ~90% of git commands you'll use. For some of these, like the
|
||
|
`git log` command, you should setup aliases
|
||
|
|
||
|
#### Manual pages
|
||
|
$ man gittutorial
|
||
|
$ man giteveryday
|
||
|
Some useful manual pages for referencing non-specifics
|
||
|
|
||
|
$ man git-rebase
|
||
|
$ git help rebase
|
||
|
$ tldr git rebase
|
||
|
For information on a single command, add a hyphen to separate out the
|
||
|
subcommand. If using `tldr` type the command as you normally would
|
||
|
|
||
|
#### Referencing commits
|
||
|
While most git commands default to `HEAD` without a commit passed, they often
|
||
|
accept other commits to operate on. Some commands also need another commit to
|
||
|
operate, like `git merge`
|
||
|
|
||
|
$ git show HEAD # References the current HEAD
|
||
|
$ git show HEAD^ # References one commit above the HEAD
|
||
|
$ git show HEAD^^ # Two commits above HEAD
|
||
|
$ git show HEAD~4 # 4 commits above HEAD
|
||
|
$ git show a22a398 # Commit starting with SHA1 a22a398
|
||
|
$ git show v0.2.0 # Commit tagged with v0.2.0
|
||
|
$ git show master # Tip of the master branch
|
||
|
$ git show origin/dev # Tip of the local copy of the origin's dev branch
|
||
|
Various examples of referencing commits. These can be mixed together for more
|
||
|
complicated referencing, though that's not too common
|
||
|
|
||
|
$ git show HEAD~4.. # All commits from 4 commits before to HEAD
|
||
|
$ git show v2.0..HEAD^ # Commits from tag v2.0 to one before HEAD
|
||
|
Some commands accept ranges of references. As expected, if one end of the range
|
||
|
is missing, it'll use a default upper/lower bound
|
||
|
|
||
|
$ git merge origin/master^
|
||
|
Merges one before the tip of the local copy of the origin's, possibly outdated,
|
||
|
master branch to the current branch. Very useful when working offline
|
||
|
|
||
|
## Project setup
|
||
|
#### New projects
|
||
|
$ git init
|
||
|
Create a new git repository in the current directory with a master branch
|
||
|
|
||
|
$ git remote add origin git@github.com:Aizuko/configs.git
|
||
|
$ git remote add origin ssh://git@github.com:22/Aizuko/configs.git
|
||
|
Sets up a remote origin on GitHub. This example uses ssh to connect, though
|
||
|
often http will also be supported. The second example specifies port 22
|
||
|
|
||
|
$ git push --set-upstream origin master
|
||
|
Pushes the master branch to the remote origin
|
||
|
|
||
|
#### Using a previous project
|
||
|
$ git clone ssh://git@github.com/Aizuko/configs.git
|
||
|
$ git clone https://github.com/Aizuko/configs.git
|
||
|
Clone a git repository from a remote. Everything will automatically be setup
|
||
|
|
||
|
$ git clone -b dev --single-branch --depth=1 ssh://git@github.com:22/Aizuko/configs.git
|
||
|
Clone the tip of the dev branch. Useful for saving storage, if you only need the
|
||
|
latest commit
|
||
|
|
||
|
.git/config
|
||
|
[remote "origin"]
|
||
|
- fetch = +refs/heads/dev:refs/remotes/origin/dev
|
||
|
+ fetch = +refs/heads/*:refs/remotes/origin/*
|
||
|
Sets git to synchronize all branches from origin, instead of just `dev`
|
||
|
|
||
|
$ git remote -v
|
||
|
List the remotes for this repository. Often useful if you want to change the
|
||
|
connection protocol
|
||
|
|
||
|
$ git remote set-url origin git@github.com:Aizuko/configs.git
|
||
|
Changes a remote. You'll rarely use this outside of changing protocols
|
||
|
|
||
|
$ git clone --depth=1 git://github.com/Aizuko/configs.git
|
||
|
Quick way to clone a Github repository without needing to login
|
||
|
|
||
|
$ git remote add upstream git@github.com:22/Aizuko/configs.git
|
||
|
Sets up another remote to track. Particularly important with forked branches
|
||
|
|
||
|
## Branches
|
||
|
Branches are a way to organize workflow into separate goals. This allows commits
|
||
|
for a feature that is still in development. Git recommends making a lot of cheap
|
||
|
branches and deleting them once merged
|
||
|
|
||
|
$ git branch -a
|
||
|
Lists all the branches on the local system
|
||
|
|
||
|
#### Git checkout changes
|
||
|
`git checkout` was one of the most common commands to run in git, since it
|
||
|
handled way too much. Starting in git 2.23 the command has been split into two
|
||
|
new commands. `switch` deals with branches while `restore` resets files
|
||
|
|
||
|
$ git restore file.txt
|
||
|
$ git checkout file.txt
|
||
|
Restore a file to how it was in the `HEAD's` commit
|
||
|
|
||
|
$ git restore --source HEAD^ file.txt
|
||
|
$ git checkout HEAD^ file.txt
|
||
|
Restore the file to match the commit one before the `HEAD`
|
||
|
|
||
|
$ git switch master
|
||
|
$ git checkout master
|
||
|
Switch to the `master` branch
|
||
|
|
||
|
$ git switch -c dev
|
||
|
$ git checkout -b dev
|
||
|
Create a new branch called `dev`
|
||
|
|
||
|
#### Removing branches
|
||
|
Once a branch's goal has been achieved and merged, there's no use in keeping it
|
||
|
around. Having a bunch of old branches is simply confusing
|
||
|
|
||
|
$ git branch --merged
|
||
|
Shows which branches have been merged. Many of these are often safe to delete
|
||
|
|
||
|
$ git branch -d merged_branch
|
||
|
Deletes a branch locally. Only deletes branches that have been fully merged into
|
||
|
an upstream, so often the remote. There's no fear in losing commits this way
|
||
|
|
||
|
$ git branch -D deadend_branch
|
||
|
$ git branch -f -d deadend_branch
|
||
|
Force deletes a local branch, regardless of whether it's been merged. You can,
|
||
|
and likely will, lose commits this way. This should only be used for local
|
||
|
experimental branches that quickly hit a dead end in development
|
||
|
|
||
|
$ git push origin --delete merged_branch
|
||
|
Deletes the branch on the remote repository as well
|
||
|
|
||
|
#### Tagging
|
||
|
Tags can be added to make referencing certain commits easier. Tags can often be
|
||
|
used instead of the rather complicated SHA1 to reference commits
|
||
|
|
||
|
$ git tag -a v0.1.0 a22a398
|
||
|
$ git tag -a v0.1.0 a22a398 -m "First version"
|
||
|
Creates an annotated tag for the commit `a22a398`. The tag will be automatically
|
||
|
signed
|
||
|
|
||
|
$ git tag -a -f v0.2.0 a22a398 -m "Add compact statusline"
|
||
|
Overwrite previous tag for a commit with a new tag. This isn't a problem for
|
||
|
tags that are only local to the system. Do not attempt for remote tags
|
||
|
|
||
|
$ git push origin v0.1.0
|
||
|
$ git push origin --tags v0.1.0 v0.2.0
|
||
|
Push up locally created tags to the remote. Tags need to be explicitly pushed.
|
||
|
Note that undoing tag pushes is really hard and shouldn't be done
|
||
|
|
||
|
## Ignoring files
|
||
|
In general there are 2 types of files you won't want to track with git: build
|
||
|
artifacts and files specific to your computer. Stopping git from tracking these
|
||
|
is done through git ignore pattern files
|
||
|
|
||
|
./.gitignore
|
||
|
Sits in the root of a git repository as a local ignore file. This will be
|
||
|
committed to the repository, so other users will ignore the same files
|
||
|
|
||
|
./.git/info/exclude
|
||
|
Acts like a `.gitignore` file specific to your system's repository. It will not
|
||
|
be committed. Useful for random files you have lying around
|
||
|
|
||
|
~/.gitignore_global
|
||
|
A `gitignore` that applies to every repository for the user. It will not be
|
||
|
committed to any particular repository, so it's more similar to a git exclude
|
||
|
file. It doesn't need any particular name, just source it in `~/.gitconfig`:
|
||
|
```
|
||
|
[core]
|
||
|
excludesfile = ~/.gitignore_global
|
||
|
```
|
||
|
|
||
|
`.gitignore` files use pattern matching similar to regex
|
||
|
|
||
|
target
|
||
|
target/**/*
|
||
|
Ignores anything in and including the `./target` directory
|
||
|
|
||
|
target/notes_[0-9].md
|
||
|
target/notes_?.md
|
||
|
Doesn't track any note files from 0-9, though will track anything higher, such
|
||
|
as `target/notes_12.md`. A `?` matches any one character, in this case also
|
||
|
matching `target/notes_a.md`
|
||
|
|
||
|
!target/*_notes_*/lec_*.md
|
||
|
Track any lecture file in any notes directory in `target`. This can match paths
|
||
|
like `target/cmput_notes_1/lec_2.md` and `target/japan_notes_12/lec_passive.md`
|
||
|
|
||
|
$ git rm --cached file.txt
|
||
|
In shell, removes a currently tracked file from tracking. This won't remove the
|
||
|
file from your system. Useful when you start ignoring a previously tracked file
|
||
|
|
||
|
[//]: # ex: set ft=markdown:tw=80:
|