Git - Notes
Basic Concepts
- Working Directory
- Staging Area (.git/index)
- .git directory
Useful Commands
Configuration files
Repository config file: .git/config
System config file: ~/.gitconfig
.git\config 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
worktree = C:/git/myrepo
ignorecase = true
[submodule]
active = .
[remote "origin"]
url = https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/myrepo
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "release/prod"]
remote = origin
merge = refs/heads/release/prod
remote = origin
merge = refs/heads/release/preprod
[branch "release/test"]
remote = origin
merge = refs/heads/release/test
[branch "release/dev"]
remote = origin
merge = refs/heads/release/dev
git remote
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32$ git remote show
origin
$ git remote -v
origin https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/myrepo (fetch)
origin https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/myrepo (push)
$ git remote show origin
* remote origin
Fetch URL: https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/myrepo
Push URL: https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/myrepo
HEAD branch: master
Remote branches:
develop tracked
feature/test tracked
master tracked
release/dev tracked
release/preprod tracked
release/prod tracked
release/test tracked
Local branches configured for 'git pull':
master merges with remote master
release/dev merges with remote release/dev
release/preprod merges with remote release/preprod
release/prod merges with remote release/prod
release/test merges with remote release/test
Local refs configured for 'git push':
master pushes to master (up to date)
release/dev pushes to release/dev (up to date)
release/preprod pushes to release/preprod (up to date)
release/prod pushes to release/prod (up to date)
release/test pushes to release/test (up to date)git push [repository] [refspec]
1
2
3
4
5$ git status
On branch release/preprod
$ git push
Everything up-to-dategit rebase (current branch is topic)
A---B---C topic* / D---E---F---G master git rebase master git rebase master topic A'--B'--C' topic* / D---E---F---G master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ git log --oneline
c60c0d9 (HEAD -> release/dev, origin/release/dev) Upgrade node version
16675e8 Update oracledb version
e5461ba Update oracledb version
4e70188 Change Nodejs version to 14
52cf369 Add GEO IP City Function
52cf369 -- 4e70188 -- e5461ba -- 16675e8 -- c60c0d9
Squash 4e70188 -- e5461ba -- 16675e8 -- c60c0d9 into one commit
$ git rebase -i 52cf369
pick 4e70188 Change Nodejs version to 14
squash e5461ba Update oracledb version # meld into previous commit
squash 16675e8 Update oracledb version # meld into previous commit
squash c60c0d9 Upgrade node versiong # meld into previous commit
52cf369 -- d59392d
$ git log --oneline
d59392d Update Nodejs version to 14 and oracledb version
52cf369 Add GEO IP City Function
git merge (current branch is master)
A---B---C topic / D---E---F---G master* git merge topic A---B---C topic / \ D---E---F---G---H master*
1
2
3
4
5# Merge topic with current branch
$ git merge topic
Updating ea2980a..532a0fa
Fast-forward
README.md | 2 +-git pull
git fetch
followed bygit merge
orgit rebase
(with --rebase)FETCH_HEAD is a short-lived ref, to keep track of what has just been fetched from the remote repository
A---B---C master on origin / D---E---F---G master* ^ origin/master in your repository A---B---C origin/master / \ D---E---F---G---H master
git fetch
git fetch --all
Fetch all remote branchesgit fetch origin master
Fetch only remote master branchgit commit
Record changes to the repository-a
Automatically stage modified and deleted files but new files are not affected (usegit add
for new files)git add
Add file contents to the staging area(index)git checkout
Switch branches or restore working tree filesgit checkout [<branch>]
-b
- create a new branch-B
- create a new branch or reset the branchgit show
Shows one or more objects (blobs, trees, tags and commits).git log
--oneline
ancestry references
^
: the parent of that commit^2
: the second parent of that commit (from the branch that was merged (say, topic))~
: first parent~2
: first parent of first parent (it traverses the first parents the number of times you specify)~~
: first parent of first parent
Git submodules
I will use my blog site to illustrate the git submodules features. Recently, I have setup a blog site by using hexo. The blog will use another hexo theme - freemind from github. First, I have forked the project as https://github.com/pnyiu/hexo-theme-freemind:
- Scenario one - include other git project in existing git project
git clone https://github.com/pnyiu/hexo-theme-freemind.git themes/freemind
The blog repository simply ignore the freemind repository stackoverflow..
└── blog
├── _config.yml
├── db.json
├── .deploy_git
├── .git
├── .gitignore
├── node_modules
├── package.json
├── public
├── scaffolds
├── source
└── themes
└── freemind
├── _config.yml
├── .git
├── .gitignore
├── languages
├── layout
├── LICENSE
├── package.json
├── README.md
└── source - Scenario two - use git submodules
UseSubmodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.
It’s quite likely that if you’re using submodules, you’re doing so because you really want to work on the code in the submodule at the same time as you’re working on the code in the main project (or across several submodules). Otherwise you would probably instead be using a simpler dependency management system (such as Maven or Rubygems).
git submodule add <repo_url>
to add submodule as below:$ git submodule add https://github.com/pnyiu/hexo-theme-freemind.git themes/freemind
Cloning into 'themes/freemind'...
remote: Counting objects: 1390, done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 1390 (delta 9), reused 5 (delta 0), pack-reused 1367
Receiving objects: 100% (1390/1390), 1.91 MiB | 302.00 KiB/s, done.
Resolving deltas: 100% (814/814), done.
Checking connectivity... done.
$ tree -L 1 -a
.
├── _config.yml
├── db.json
├── .deploy_git
├── .git
├── .gitignore
├── .gitmodules
├── node_modules
├── package.json
├── public
├── scaffolds
├── source
└── themes
$ cat .gitmodules
[submodule "themes/freemind"]
path = themes/freemind
url = https://github.com/pnyiu/hexo-theme-freemind.git- New file
.gitmodules
is created to keep track the submodules path and url. - Git would get the changes and update the files in the subdirectory but will leave the sub-repository in what’s called a
detached HEAD
state. This means that there is no local working branch (likemaster
, for example) tracking changes. - Doesn’t track submodule contents when you’re not in that directory
- For new project with submodules, use (
git submodule init
andgit submodule update
) orgit clone --recursive
to initialize and fetch all data from that project and submodules.
- New file
Conflicts with modified files when switch to another branch
It is common to work with multiple branches. For example, if we are working the file test.html:
- Update test.html in master branch
- Switch to testbranch branch, update and commit the changes to git
- Switch to master branch, update the test.html and do not commit the changes Then, switch to testbranch but failed
$ git init |

Use ssh for authentication
GitHub
- Generate new SSH key / use existing SSH key
1
2
3
4
5
6
7
8
9
10# List your existing SSH keys
$ ls ~/.ssh -l
total 40
-rw-r--r-- 1 calviny calviny 172 Jul 21 11:52 config
-rw------- 1 calviny calviny 1679 Jul 4 2019 pnyiu
-rw-r--r-- 1 calviny calviny 404 Jul 4 2019 pnyiu.pub
-rw------- 1 calviny calviny 25292 Jul 21 12:00 known_hosts
# Generating a new SSH key
ssh-keygen -t ed25519 -C "your_email@example.com" - Add a new SSH key to GitHub
- Click your profile photo, then click Settings
- Click SSH and GPG keys
- Click New SSH key or Add SSH key
- Copy and paste the public key in the Key field
- Update ~/.ssh/config
Host github.com
User git
IdentityFile ~/.ssh/pnyiu - Test SSH connection
ssh -T git@github.com
AWS CodeCommit
- Generate new SSH / use existing SSH key
- Upload to AWS by Identity and Access Management (IAM)
- Update ~/.ssh/config (refer to GitHub example)
Host git-codecommit.*.amazonaws.com
User <SSH key ID>
IdentityFile ~/.ssh/pnyiu - Clone the repository
git clone ssh://<SSH key ID>@git-codecommit.ap-east-1.amazonaws.com/v1/repos/my-repo
- Check the remote configuration
$ git remote show origin
* remote origin
Fetch URL: ssh://<SSH key ID>@git-codecommit.ap-east-1.amazonaws.com/v1/repos/my-repo
Push URL: ssh://<SSH key ID>@git-codecommit.ap-east-1.amazonaws.com/v1/repos/my-repo