heo-jae-won@home:~$

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