Git 简单操作

密钥对

生成密钥对

$ ssh-keygen -t rsa -b 4096 -C "[email protected]"
or
$ ssh-keygen -t ed25519 -C "[email protected]"        # 建议使用 Ed25519 算法

对已经生成的私钥修改 password

$ ssh-keygen -p -f ~/.ssh/id_ed25519

macOS Sierra 10.12.2 及以后的macOS 系统,可以使用 keychain 存储口令,首先修改 ~/.ssh/config

Host *
    IdentityFile ~/.ssh/id_ed25519
    AddKeysToAgent yes
    UseKeychain yes

存储你的 key 口令

$ ssh-add -K ~/.ssh/id_ed25519

以用户名密码操作 git 的,在 MacOS 下也可以用 keychain 来存储

$ git config --global credential.helper osxkeychain

常规操作

Git 初始设置

$ git config --list           # 显示当前配置
$ git config --global -e      # 全局 git 配置
$ git config --global user.name "username"            # 全局配置提交者用户名
$ git config --global user.email [email protected]   # 全局配置提交者邮箱
$ git config --global alias.ll "log --graph --pretty=format:'%C(yellow)%h%Creset -%C(cyan)%d%Creset %s %Cgreen(%an, %cr)' --abbrev-commit"

建立仓库并初始化

$ cd overlay && git init

项目暂存

$ git add .               # 添加所有文件至暂存
$ git add file            # 添加文件至暂存
$ git add dir             # 添加目录至暂存
$ git rm file             # 删除工作区文件,并将这次删除放入暂存
$ git rm --cached file    # 删除记录中文件
$ git mv old new          # 改名操作,并将这个操作置入暂存

提交修改

$ git commit -m 'commit message'
$ git commit --amend -m "commit other"          # 修正之前的提交注释

上传 origin 到远程的 master 分支

$ git remote add origin [email protected]:user/repo.git
$ git push origin master

一般性步骤

$ cd repo
$ git add .
$ git commit -m 'commit'
$ git remote add origin [email protected]:user/repo.git      #仅第一次指定 remote 地址,以后 push 时可以省略
$ git push origin master

更新文件

$ git pull origin            #更新,chekout 代码
$ git fetch origin           #更新远端 repository 信息
$ git merge origin master    #合并
$ vi README
$ git commit -a
$ git push origin master     #提交

创建分支

$ git branch
$ git branch new-branch
$ git checkout new-branch
$ touch newreadme
$ git add newreadme
$ git commit -a -m 'add newreadme'
$ git push origin new-branch

创建空白分支

$ git checkout --orphan gh-pages
$ git rm -rf .
$ git add .
$ git commit -m 'new branch: gh-pages'
$ git push origin gh-pages

删除远程分支

$ git push origi :new-branch

删除本地分支

$ git branch -d new-feature

有时会出现 GitHub repo 分支已删除,但本地电脑没有删除的情况

$ git branch -d -r remotename/branchname

远端分之删除,A 电脑删除对应分支,B 电脑还保留着对应分支

$ git remote prune remotename

合并进 master

$ git checkout master
$ git merge new-feature
$ git branch
$ git push

生成压缩包

$ git archive

github 回滚

$ git branch old                            #创建 old 分支
$ git push origin old:old                   #push 到远程 github
$ git reset --hard id                       #本地回滚到某版本,并随后将 github 上默认分支改为 old
$ git push origin :master                   #删除 github 上的 master 分支
$ git push origin master                    #push重新创建的master分支
$ git push origin :old                      #将 github 默认分支改为 master,并删除远程 old 分支
$ git clone [email protected]:user/repo.git    #重新 clone

撤销本地更改

$ git checkout file                         # 检出修改的文件

撤销暂存更改

$git revert HEAD file

撤销提交的版本

$ git revert HEAD                           #撤销前一次commit
$ git revert HEAD^                          #撤销前前一次commit
$ git revert commit id                      #撤销指定的版本

$ git reset --hard id
$ git push origin HEAD --force

如果仅撤销 commit message,则

$ git reset --soft id
$ git commit -m 'xxx'

$ git commit --amend

.gitIgnore 文件忽略哪些不被 Git 跟踪的文件,在根目录下生成 .gitignore 文件

# Can ignore specific files
.DS_Store
# Use wildcards as well
*~
*.swp
# Can also ignore all directories and files in a directory.
tmp/**/*
# Ignore all dotfiles...
.*
# except for .gitignore
!.gitignore

删除悬空对象(dangling objects)

$ git gc --prune=0
$ git reflog expire --expire-unreachable=0 --all

获取最近 10 个 commit 历史

$ git clone --depth 10 https://github.com/user/repo.git

在本地已有项目上保留 10 个历史记录

$ git fetch origin --depth 10
# 如有冲突,则
$ git reset --merge refs/remotes/origin/master

commit 历史操作

永久删除历史文件

$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch /path/file' --prune-empty --tag-name-filter cat -- --all
$ rm -rf .git/refs/original/
$ git reflog expire --expire=now --all
$ git gc --prune=now
$ git gc --aggressive --prune=now

删除某 commit id 之前的所有历史,假设 commit id 为 1234567

$ git checkout --orphan temp 1234567
$ git commit -m 'first'
$ git rebase --onto temp 1234567 master
$ git branch -D temp
$ git rebase --committer-date-is-author-date 1234567

修改最近一次 commit id 时间

$ GIT_COMMITTER_DATE="Mon 2 May 20:19:19 2011 +0800" GIT_AUTHOR_DATE="Mon 2 May 20:19:19 2011 +0800" git commit --amend --no-edit --date "Mon 2 May 20:19:19 2011 +0800"

修改之前某次 commit id 时间

$ git checkout commit-id
通过上面的方法修改 commit-id 时间
通过 git cherry-pick 将之后的 commit-id 合并过来

修改首次 commit 时间

$ gitrebase -i --root
$ GIT_COMMITTER_DATE="Mon 2 May 20:19:19 2011 +0800" GIT_AUTHOR_DATE="Mon 2 May 20:19:19 2011 +0800" git commit --amend --date "Mon 2 May 20:19:19 2011 +0800"
$ git rebase --continue
$ git rebase --committer-date-is-author-date --root

修改某个commit id 的时间(不建议)

$ git filter-branch --env-filter \
'if [ $GIT_COMMIT = 1234567 ]
 then
     export GIT_AUTHOR_DATE="Sat May 19 01:01:01 2007 +0800"
     export GIT_COMMITTER_DATE="Sat May 19 01:01:01 2007 +0800"
 fi'

修改最近一次 commit author

git commit --amend --author="Author name <[email protected]>" --no-edit
git rebase --contine

commit 相关的变量

GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
GIT_AUTHOR_DATE
GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL
GIT_COMMITTER_DATE
EMAIL

给指定的提交者的 commit 加上 gpg

$ git filter-branch -f --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]; then
    git commit-tree -S "$@";
 else
    git commit-tree "$@";
fi' HEAD

修改 email

$ git filter-branch -f --env-filter '
if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" -o "$GIT_AUTHOR_EMAIL" = "[email protected]" ]; then
    export [email protected]
    export [email protected]
fi' --tag-name-filter cat -- --branches --tags
# 一些用于设置的变量

资料

log 参数
参数 说明
%H commit hash
%h commit short hash
%T tree hash
%t tree short hash
%P parent hash
%p parent short hash
%an 作者名字
%aN .mailmap 中对应的作者名字
%ae 作者邮箱
%aE .mailmap 中对应的作者邮箱
%ad –date=制定的日期格式
%aD RFC2822 日期格式
%ar 日期格式,例如:1 day ago
%at UNIX timestamp 日期格式
%ai ISO 8601 日期格式
%cn 提交者名字
%cN .mailmap 对应的提交的名字
%ce 提交者邮箱
%cE .mailmap 对应的提交者的邮箱
%cd –data=制定的提交日期的格式
%cD RFC2822 提交日期的格式
%cr 提交日期的格式,例如:1day ago
%ct UNIX timestamp 提交日期的格式
%ci ISO 8601 提交日期的格式
%d ref 名称
%e encoding
%s commit 信息标题
%f 过滤 commit 信息的标题使之可以作为文件名
%b commit 信息内容
%N commit notes
%gD reflog selector, e.g., refs/stash@{1}
%gd shortened reflog selector, e.g., stash@{1}
%gs reflog subject
%Cred 切换至红色
%Cgreen 切换至绿色
%Cblue 切换至蓝色
%Creset 重设颜色
%C(color) 制定颜色,as described in color.branch.* config option
%m left right or boundary mark
%n 换行
%% a raw %
%x00 print a byte from a hex code
%w([[,[,]]]) switch line wrapping, like the -w option of git-shortlog(1).