Git

https://www.notion.so/Git-083df52831464e92b81baba662265434

Download and Installation

https://git-scm.com/downloads

Commit

Commit with empty message

1
2
git config --global alias.nccommit "commit -a --allow-empty-message -m ''"
git nccommit

Change commit info

1
2
3
4
git commit --amend --author="Bendy Zhang <zbatbndy.net>" --no-edit

git commit --amend --date="Sun Aug 7 13:05 2022 +0800" --no-edit
GIT_COMMITTER_DATE="Sun Aug 7 14:10 2022 +0800" git commit --amend --no-edit

Branch

New branch from remote

1
git checkout -b localBranch origin/remote_branch

Push changes to new branch

1
2
git checkout -b newBranch
git push -u origin newBranch  # -u is short for `-set-upstream`

Bind local branch with remote branch

1
git branch --set-upstream-to=origin/remote_branch your_branch

Remove multiple branches

1
git branch -d `git branch --list '3.2.*'`

Reset local branch to remote branch

1
git fetch origin && git reset --hard origin/master

Merge

  • git merge master
  • git merge master --squash // merge master branch to current branch and keep changes without commits
  • git rebase master
  • git rebase --interactive --root // squash all of your commits down to the root commit
  • git cherry-pick <commitid> // pick up specified commit to current branch, if conflicts, resolve it and git add . && git cherry-pick --continue
  • git cherry-pick A..B The commit A should be older than B which will not include A. If requires A, please use A^~B

Undoing Things

  • Remove from cache

    1
    
      git rm -r --cached <your-folder>
    
  • Overwrite commit

    1
    2
    3
    
      git commit -m 'initial commit'
      git add .
      git commit --amend
    
  • Unstaging a Staged File
    • git reset to unstage all files, they will be removed from the staging area back to your working directory.
    • git reset HEAD <file>...
    • git checkout -- <file>... to discard changes in working directory
    • git restore --staged <file>... to unstage into change list
  • Unmodifying a Modified File
    • git checkout -- <path>
    • git checkout -- . to discard your entire working directory, head back to the root of your project.
    • git reset --soft <commit> to unstage commits softly, git reset --soft HEAD~1 to unstage your last commit
  • View all logs git reflog
  • Remove untracked files & directories
    • Print out files and directories which will be removed (dry run), run git clean -n -d
    • To remove directories, run git clean -f -d or git clean -fd
    • To remove ignored files, run git clean -f -X or git clean -fX
    • To remove ignored and non-ignored files, run git clean -f -x or git clean -fx

Stash Usage

1
2
git stash  // stash current changes
git stash pop  // pop last stash and remove from history
1
2
3
4
git stash save 'message'  // stash current changes with message
git stash list // show all stashes
git stash apply <id>  // apply <id> stash

Tag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# create tagg
git tag -a <tagname> -m '<tagcomment>'

# show tags
git tag

# show specified tag
git show <tagname>

# push to remote
git push origin <tagname>

# push all tags to remote
git push origin --tags

# checkout tag
git checkout <tagname>

# delete tag
git tag -d <tagname>

# delete remote tag
git push origin <tagname>
git push --delete origin tagname

Clone Subfolder

By following ways, you will get the folder fastest that you want.

1
2
3
4
git clone -n --depth=1 --filter=blob:none git@github.com:bndynet/bndynet.git
cd bndynet
git sparse-checkout set "/_data/*" --no-cone
git checkout

Or

1
2
3
4
5
6
7
git init
git sparse-checkout init --no-cone
git sparse-checkout set "/_data/*" --no-cone
git remote add origin git@github.com:bndynet/bndynet.git
git config core.sparsecheckout true
echo "partialclonefilter = blob:none" >> .git/config
git pull --depth=1 origin master

Subtree

1
2
3
// with squash, this repo history commits will not be merged into parent repo
git subtree add --prefix=subfolder https://github.com/subrepo.git master --squash
git subtree push --prefix=dist https://github.com/subrepo.git gh-pages

Workflow

with Git: Fork, Branching, Commits, and Pull Request

  1. Fork a repo.
  2. Clone the forked project to your local machine:

    git clone git@github.com:USERNAME/<forked_repo>

  3. Configure remotes:

    git remote add upstream git://github.com/<origin_repo>

  4. Create a branch for new feature:

    git checkout -b my-new-branch

  5. Develop on my-new-branch branch only, but Do not merge my-new-branch branch to the your master (as it should stay equal to upstream master)!!
  6. Commit changes to my-new-branch branch:

    1
    2
    
     git add .
     git commit -m "commit message"
    
  7. Push branch to GitHub, to allow your mentor to review your code:

    $ git push origin my-new-branch

  8. Repeat steps 5-7 till development is complete.
  9. Fetch upstream changes that were done by other contributors:

    $ git fetch upstream

  10. Update local master:
1
2
git checkout master
git pull upstream master

ATTENTION: any time you lost of track of your code – launch “gitk —all” in source folder, UI application come up that will show all branches and history in pretty view, explanation.

  1. Rebase my-new-branch branch on top of the upstream master:
1
2
git checkout my-new-branch
git rebase master
  1. In the process of the rebase, it may discover conflicts. In that case it will stop and allow you to fix the conflicts. After fixing conflicts, use git add . to update the index with those contents, and then just run:
1
git rebase --continue
  1. Push branch to GitHub (with all your final changes and actual code):

We forcing changes to your issue branch(our sand box) is not common branch, and rebasing means recreation of commits so no way to push without force. NEVER force to common branch.

1
git push origin my-new-branch --force
  1. Created build for testing and send it to any mentor for testing.
  2. Only after all testing is done – Send a Pull Request.

Attention: Please recheck that in your pull request you send only your changes, and no other changes!! Check it by command: git diff my-new-branch upstream/master

Submodule

1
2
3
4
5
6
7
8
9
10
git submodule add submodule-repo path
git submodule update --init --recursive
git rm submodule-name
git rm submodule-name --cached
// update submodule to master
cd submodule_folder
git checkout master
cd ../
git add .
git commit -m ''

Common Alias

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
git config --global alias.s "status"
git config --global alias.a "\!git add . && git status"
git config --global alias.au "\!git add -u . && git status"
git config --global alias.aa "\!git add . && git add -u . && git status"
git config --global alias.b "branch"
git config --global alias.c "commit"
git config --global alias.cm "commit -m"
git config --global alias.ca "commit --amend"
git config --global alias.ac "\!git add . && git commit"
git config --global alias.acm "\!git add . && git commit -m"
git config --global alias.l "log --graph --all --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'"
git config --global alias.ll "log --stat --abbrev-commit"
git config --global alias.lg "log --color --graph --pretty=format:'%C(bold white)%h%Creset -%C(bold green)%d%Creset %s %C(bold green)(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
git config --global alias.llg "log --color --graph --pretty=format:'%C(bold white)%H %d%Creset%n%s%n%+b%C(bold blue)%an <%ae>%Creset %C(bold green)%cr (%ci)' --abbrev-commit"
git config --global alias.d "diff"
git config --global alias.master "checkout master"
git config --global alias.main "checkout main"
git config --global alias.alias "\!git config --list | grep 'alias\.' | sed 's/alias\.\([^=]*\)=\(.*\)/\1\     => \2/' | sort"
git config --global alias.hi "\!echo 'Hello World!'"
git config --global --unset alias.hi

Log

1
$ git log --follow --pretty=oneline things/text.txt    view log of the renamed file
1
git log --author="zb@bndy.net" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

Output:

1
added lines: 545140, removed lines: 1152979, total lines: -607839
1
git log --pretty=format:%h,%an,%ae,%ad,%s --name-only

Output:

1
2
3
acb533d,Bendy Zhang,zb@bndy.net,Sun Jul 12 16:17:14 2020 +0800,commit message
.gitignore
README.md
  • -since=<date>, --after=<date> Show commits more recent than a specific date.
  • -until=<date>, --before=<date> Show commits older than a specific date.
  • --author=<pattern>, --committer=<pattern> Limit the commits output to ones with author/committer header lines that match the specified pattern (regular expression). With more than one -author=<pattern>, commits whose author matches any of the given patterns are chosen (similarly for multiple -committer=<pattern>).

Pretty Formats

https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt-emHem

QA

.gitignore can not ignore a file.

Need run following command to remove all files from the repository and add them back.

1
2
git rm -rf --cached .
git add .
This post is licensed under CC BY 4.0 by the author.