git command
clone branch
- branch clone
git clone -branch <branchname> <remote-repo-url>
- getting remote info
- updating remote branch info
- move to there after clone
git fetch origin
git branch -r
git switch [remote branch]
branch manipulation
- make new branch and move
- delete remote and local branch both
- rename branch
- see default branch
git switch -c [branch]
git push origin --delete [branch이름]
git branch -m [current branch] [future branch name]
git remote show origin
remove local change
git restore [filename]
adding file staging area
- add file in staging area for only update and delete
git add -u
- add file in staging area for all
git add .
- removing all staged file
git restore --staged .
add file to just before commit
- no need to increase commit for adding file
git add [file]
git commit --amend -m "message" # or git commit --amend
- removing just before commit, preseving file on worksapce
git reset --mixed
when u want to do experiment about bugs using completely different branch
git stash push -m "my work before fixing a bug"
git switch -c fix/feature
git add .
git commit -m "implement fix"
git fetch origin
git rebase origin/main
git push -u origin fix/feature
# open GitHub PR (fix/feature → main)
git switch main
git branch -d fix/feature
git stash drop stash@{0} # only if you still have stash left
- simplified version that dont use rebase
git switch main
git pull
git switch -c fix/feature
# work + commit
git add .
git commit -m "fix bug"
git push -u origin fix/feature
# open PR
git switch main
git branch -d fix/feature
git command customizing
vim ~/.gitconfig:
- it looks like below
- ls is showing commit log pretty
- rs is checking cleared stash list
- dl is checking commit log under some condition
- fl is showing file list that i develope from certain date
[user]
email = 222
name = 333
[alias]
lo = log --oneline
ls = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate
rs = fsck --no-reflog | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ci %H" | sort
dl = git log --name-only --date=local --author=Heo-Jae-Won --since="2024-01-03"
fl = git log --name-only --author=Heo-Jae-Won --date=local --since="2024-01-03" | egrep -v "^commit|^Date:|^Merge:|^Author:|^\s" | sort | uniq
- if we execute this one, we can show this one
git config --list
alias.ls=log --pretty=format:%C(yellow)%h%Cred%d\ %Creset%s%Cblue\ [%cn] --decorate
alias.ll=log --pretty=format:%C(yellow)%h%Cred%d\ %Creset%s%Cblue\ [%cn] --decorate --numstat
.
.
git username email config
git config user.name [username]
git config user.email [email]
seeing previous commit content
git restore --source HEAD~0 [파일이름] ---> current file. useless
git restore --source HEAD~1 [파일이름] ---> 1 commit before file.
git restore --source HEAD~2 [파일이름] ---> 2 commit before file.
git restore [파일이름]---> go back to original HEAD
HEAD~ and HEAD^ diff for merge commit
- HEAD~ is about commit history
- HEAD~1 = C
- HEAD → C → B
- HEAD~2 = B
- HEAD~3 = A
- HEAD^ is about commit parent
- HEAD^ = HEAD^1 = C
- HEAD^2 = F
E -- F
/ \
A -- B -- C -- D (HEAD)
cherry pick from dev to main
- let’s suppose below commit exists
cderf21 --> HEAD
rtqwrr51 --> HEAD~2
- below is dangerous, cuz cherry-pick picks out just diff.
- so, if target branch doesnt have the file needed for commit cdef21, conflicts happends.
- because file is created in commit rtqwrr51. so it’s safer to cherry-pick range.
git cherry-pick cdef21
- i want to get commit from HEAD to HEAD~2, then i must execute it reversely
- from index is not included. so need to be started from one point before
git cherry-pick rtqwrr51^..cdef21
- combining all commit into 1
git cherry-pick --no-commit rtqwrr51^..cdef21
git commit -m "final combined work"
github PR
rebase:replacing cherry pick
- above one can be replaced by rebase
- but it must be cautious that rebase must be done in local commit, not pushed one
git rebase -i rtqwrr51^
- text would be shown like below
pick rtqwrr51
pick abc123 --->squash
pick def456 --->squash
pick cdef21 --->squash
git commit --amend -m "Implement feature X (final version)" # (if message editor doesnt open)
git push # (if already published --force-with-lease)
- if it’s already published in remote, teammates should do following one whether it’s used on my own or shared
git fetch
git rebase origin/mybranch
git conflict on branch when using git pull
# fixing content
git add [fixed file]
git merge --continue
- structure would be like below
M = merge commit (newly created)
D is NOT rewritten
X → Y is NOT rewritten
Git combines both histories
A --- B --- C --- D ---> this is merged version
\ \
X --- Y --- M
rebase:fix local commit message before publishing to remote
git rebase -i HEAD~n :
pick -> reword
change commit message -> :wq
rebase:PR
- in my feature branch is executed
- only for local commit
git fetch origin
git rebase -i origin/dev #(if target is main, origin/main)
- if conflicts happens
- after rebase, already aligned commit. so it becoms fast forward –> clean history
git add
git rebase --continue
git push origin feature/my-work
open PR → feature → dev
- basic form of rebase is like below
- it means Git will rebase branch onto upstream
- but latter one is used often
- it means “Take the current branch (HEAD) and replay its commits on top of origin/dev.”
git rebase <upstream(origin/dev)> <branch(feature/login)>
git rebase origin/dev
- so two combination is usally used for rebasing
git switch feature/branch
git rebase origin/dev
reflog:showing history for git conduct
- HEAD in reflog doesnt mean branch’s head
- therefore, HEAD@{0} and HEAD@{2} can be actually refer to same thing
- reflog show command can limit target of command like below
git reflog show HEAD@{2.days.ago}
git reflog show HEAD@{1.month.ago}
git reflog show HEAD@{1.week.ago}
git reflog show master@{0} master@{yesterday}
reflog:restore file
- git reflog show –> finding a commit hash that i need to recover
- after restoring, file is recreated in working directory, not inside Git history
- so need to again add and commit
git log --all -- '*file*'
commit 8f3a91c2d7b5a4c1e9a0f2b6c7d8e9f1a2b3c4d5
git ls-tree -r <commit-hash>
100644 blob aaa111 src/app/main.py
100644 blob bbb222 src/utils/helper.py
git restore --source <commit> <file-path>
temp save
- we can save our work to temp space
- but untracked file cannot be target of stash
git stash push -m "my work before fixing a bug"
git stash pop
revert:commit delete from remote repo
- let’s suppose below commit flow
A — B — C — D — E — F (latest = F, commit123 = C)
* f6f6f6f (HEAD -> main) Commit F
* e5e5e5e Commit E
* d4d4d4d Commit D
* c3c3c3c Commit C <-- commit123
* b2b2b2b Commit B
* a1a1a1a Commit A
- then commit from C to F is reverted
git revert --no-commit C^..F
git push origin master
log reading
- origin/HEAD is not a branch HEAD
- a pointer to the default branch on the remote
- usually points to origin/main or origin/master
- origin/main is remote repo recent commit
- main is local repo recent commit
- when origin/main and main is together, it means no divergence from local and remote
- everything up to date.
de12b0e (origin/main, origin/HEAD, main) commit
- local branch is fully up to date with the remote
- HEAD -> means that i am not detached state, which means on this branch
- if no HEAD ->, it means i am detached state
4c6cfcc (HEAD -> feature/recommend, origin/feature/recommend) commit2
- 785cd77 HEAD -> feature/authority-profile doesnt be written remote origin.
- it means that remote feature/authority-profile has ahead commit, which means needs git pull
- actually, other developer can commit on my branch if it’s shared branch.
- 68aa468 (master) Merge pull request #122
785cd77 (HEAD -> feature/authority-profile) Feat: generate role
- (feature/dev_wsg) and (origin/feature/dev_wsg) is diverged
- it means local has more ahead commit
82174d3 (feature/dev_wsg) fix: exclude deactivated account#2
8339e87 fix: exclude deactivated account
afdfd6d add: search word option(=address)
35d69ef (origin/feature/dev_wsg) adding profile path
- 8957fea origin/hotfix/add-db-tls doesnt be written (origin/hotfix/add-db-tls, hotfix/add-db-tls)
- in this case, origin/hotfix/add-db-tls is not about ahead or behind when there is no hotfix/add-db-tls in commit log
- it means that i dont publish hotfix/add-db-tls on my local
8957fea (origin/hotfix/add-db-tls) add-db-enable-tls
merge and ff
- let’s suppose this kind of commit flow
A ー Bー Cー D.
- i diverge branch from main D commit
- commit on my branch is E and F is executed.
main: A — B — C — D — G
\
feature: E — F
- in this case, when using git status below message is shown
- showing ahead and behind simultaneously means diverging of branch
1 commit ahead, 2 commit behind
- in this case, ff is impossible
- history diverged at D:
- main has G
- my feature has E, F
- so Git cannot just “move the pointer”
- both branches have unique commits.
- Therefore, fast-forward is impossible
- merge commit is generated
[merge]
A — B — C — D — G
\
M
/
E — F
- if u want flow like below,
A — B — C — D — G — E' — F'
- rebase is needed
git switch feature
git rebase main
- then when ff is possible?
- when no advanced commit on main exists, ff is possible
main: A — B — C
feature: D — E
- if merging operation is finished, git status shows like this message
up to date