Git高级玩法

SSH免密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 如果没有 .ssh隐藏文件,则需要先打开 `git bash`,并执行
$ mkdir ~/.ssh
$ chmod +700 ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa -C "yuzhouwan@email.com"
# 将 ~/.ssh/id_rsa.pub中的公钥加入 github/gitlab
$ ssh -T git@github.com
Hi asdf2014! You've successfully authenticated, but GitHub does not provide shell access. '
# http -> ssh
$ git remote -v
origin https://github.com/asdf2014/yuzhouwan (fetch)
origin https://github.com/asdf2014/yuzhouwan (push)
$ git remote set-url origin git@github.com:asdf2014/yuzhouwan.git
$ git remote -v
origin git@github.com:asdf2014/yuzhouwan.git (fetch)
origin git@github.com:asdf2014/yuzhouwan.git (push)

Github加速

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Ctrl + R (管理员权限运行)
# notepad "%SystemRoot%\system32\drivers\etc\hosts"
# https://asm.ca.com/zh_cn/ping.php
192.30.253.112 github.com
151.101.56.133 assets-cdn.github.com
192.30.253.116 api.github.com
192.30.253.121 codeload.github.com
# 中国 - 香港特别行政区 (hkhkg02)
192.30.253.112 github.com
151.101.100.133 assets-cdn.github.com
192.30.253.116 api.github.com
192.30.253.121 codeload.github.com

Github Fetch

Normal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Github上对某一个开源项目进行 fork
https://github.com/airbnb/superset
https://github.com/asdf2014/superset (forked from airbnb/superset)
# 本地获取 fork出来的 asdf2014/superset
$ git init
$ git remote add origin https://github.com/asdf2014/superset.git
$ git remote -v
origin https://github.com/asdf2014/superset.git (fetch)
origin https://github.com/asdf2014/superset.git (push)
## 发现并没有 airbnb/superset的 origin/master,可以在直接往 asdf2014/superset提交,然后在 github上进行 pull request的创建
https://github.com/airbnb/superset/pull/2136 (Fix werkzeug instance was created twice in Debug Mode (#2135) #2136)
$ git fetch https://github.com/airbnb/superset.git master:temp
$ git diff temp
$ git merge temp
$ git branch -d temp

Fetch all tags

1
2
3
4
5
$ git fetch --tags
$ git checkout tags/release-3.4.6
$ git checkout master
Previous HEAD position was 1285c982... ZooKeeper 3.4.6 release.
Switched to branch 'master'

Git Tag

Create tag

1
2
3
4
5
6
7
8
9
10
11
# 创建简单的标签
$ git tag v0.0.1
# 创建带有附注的 tag
$ git tag -a v0.0.2 -m "v0.0.2"
# 展示 tag信息
$ git show v0.0.2
# 给指定的 commit,打 tag
$ git tag -a v0.0.3 6d23400

Submit tag

1
2
3
4
$ git push origin v0.0.2
# push本地所有标签
$ git push origin –tags

Pull with specific tag

1
2
3
4
5
6
7
8
$ git clone
# 列出 tag列表,并 checkout到指定的 tag
$ git tag -l
$ git checkout tags/<tag_name>
# checkout到指定的 tag,并创建一个新的 branch
$ git checkout tags/<tag_name> -b <branch_name>

Delete tag

1
2
3
4
5
6
7
8
# 删除本地 Tag
$ git tag -d v3.4.6.0
Deleted tag 'v3.4.6.0' (was 0e48a03a)
# 删除远程 Tag
$ git push origin :refs/tags/v3.4.6.0
To http://github.com/asdf2014/zookeeper.git
- [deleted] v3.4.6.0

Git Commit

Commit Merge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git log --pretty=oneline
651cc60d971aba93bdde645b6331c33068462645 Merge branch 'master' of https://github.com/asdf2014/superset
415610958494446ccd37c0c87da98eba56af42ac Merge branch 'temp'
b881140282893fa4add183a2b3f2637968f95069 Merge branch 'master' into master
f2bf3160583533bd0dc5004f248f81251aa8c57e Add NUMERIC num_type (#2127)
6a0fefdbd542da4ea313313a191eadd1efe58faa Using the time zone with specific name for querying Druid
9cd38fa1eda63152c27b76c29dd948f29444b686 little code refactor in models.py (#2124)
$ git reset --soft HEAD~2 &&
$ git commit --edit -m "$($ git log --format=%B --reverse HEAD..HEAD@{1})"
[master fd41c16] Add NUMERIC num_type (#2127)
1 file changed, 1 insertion(+), 1 deletion(-)
# 更改之后的 commit信息
fd41c1608579408fcd26d0dd03adf0d461599101 Add NUMERIC num_type (#2127)
6a0fefdbd542da4ea313313a191eadd1efe58faa Using the time zone with specific name for querying Druid
9cd38fa1eda63152c27b76c29dd948f29444b686 little code refactor in models.py (#2124)

问题

failed to push some refs
描述
1
2
3
4
5
6
7
8
Username for 'https://github.com': asdf2014
To https://github.com/asdf2014/superset.git
! [rejected] ext_deprecation_warning -> ext_deprecation_warning (non-fast-forward)
error: failed to push some refs to 'https://github.com/asdf2014/superset.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: '$ git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in '$ git push --help' for details.
解决
1
$ git push -u origin ext_deprecation_warning --force

Commit Remove

1
2
$ git reset --hard <sha1-commit-id>
$ git push origin HEAD --force

Commit Change

只修改最后一次提交

1
2
3
4
5
6
7
# 格式
$ git commit --amend
$ git commit --amend -m "New commit message"
$ git commit --amend --author="Author Name <email@address.com>"
# 示例
$ git commit --amend -m 'remove warnings.simplefilter from cli.py into superset for PEP (#2137)'
$ git commit --amend --author="asdf2014 <yuzhouwan@gmail.com>"

修改之前的提交信息

1
2
3
$ git rebase -i HEAD~2
pick xxxx
reword yyyy

Reset into Specific Commit

1
2
3
4
5
# It will make your local code and local history be just like it was at that commit. But then if you wanted to push this to someone else who has the new history, it would fail.
$ git reset --hard c14809fa
# It will make your local files changed to be like they were then, but leave your history etc. the same.
$ git reset --soft c14809fa

Squash Commits into a Single Commit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看哪些 commits需要进行合并
$ git log --pretty=oneline
# 合并最后 11个 commit
$ git rebase -i HEAD~11
pick xxxx yyyy
pick xxxx yyyy
pick xxxx yyyy
# 将需要压缩的 commit之前的 `pick`替换为 `squash`
pick xxxx yyyy
squash xxxx yyyy
squash xxxx yyyy
$ git commit --amend -m 'The log length has exceeded the limit of 4 MB in Travis'
$ git push origin travis_log --force
# 如需解决冲突后,继续进行 rebase操作,可执行
$ git rebase --continue
# 如果想中断 rebase操作,则执行
$ git rebase --abort
# 更多细节
$ git rebase --help

其他

回滚
1
$ git reset --hard ORIG_HEAD
指定 commit number
1
$ git rebase <commit number>
合并 branch改动到 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
25
26
# 会将 branch里的 commit排到 master的顶部,避免带 Merge信息的 `空commit` 出现
$ git checkout <branch name>
$ git rebase -i master
# 如果已经在当前 branch执行了 git merge master,并解决了冲突,可以直接执行下面这行命令,完成 rebase操作
$ git rebase --root --onto master --preserve-merges
# 万一出现太多的问题,难以解决,可以采用如下暴力的方式 (在意 commit信息的,请预先备份好)
$ git rebase --abort # 首先 abort之前的 rebase流程
$ git checkout code_refactoring
$ git checkout -b re2
$ git branch root bbb61e638b391d29 # 以当前 branch未做任何修改之前的 commit为基础,创建 root分支
$ git checkout re2
$ git diff master > ../123.patch # 当前 branch相对 master已经做的修改打出 patch文件
$ git checkout master
$ git checkout -b r2
$ git apply ../123.patch # 以 master为基础,apply分支上做的修改
$ git diff master
$ git status
$ git diff --name-status | wc -l # 确认修改的文件数 是否正确
$ git add .
$ git status
$ git diff master
$ git commit -m 'Improve `collection` related things that reusing a immutable object instead of creating a new object'
$ git status
$ git push origin r2:code_refactoring -f

Git Reset

回退某一个文件的修改

1
$ git reset HEAD^ yuzhouwan.txt

Git Checkout

checkout的同时创建新的branch

1
$ git checkout -b <new_branch_new>

撤销某个文件的修改

1
$ git checkout -- <file>

Git Branch

1
2
3
4
5
$ git checkout -b <branch>
$ git push -u origin <branch>
$ git branch -m <oldname> <newname>
$ git branch -m <newname>

Git Diff

Git diff two commits

1
$ git diff 1285c982 b0aaa7de > v3.4.6_vs_v3.4.10.patch

Git Remote

Change remote url

1
$ git remote set-url origin <url>

Pull specific tag from remote

1
$ git pull origin release-1.7.7:release-1.7.7

Git Config

1
2
3
4
5
$ git config user.name "asdf2014"
$ git config user.email "yuzhouwan@gmail.com"
$ git reset .
$ git add -A
$ git diff --staged

Git Proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 命令
$ git config --global http.proxy 'http://192.168.1.101:8888'
$ git config --global https.proxy 'https://192.168.1.101:8888'
$ git config --global http.proxy 'socks5://127.0.0.1:1080'
$ git config --global https.proxy 'socks5://127.0.0.1:1080'
# 修改配置
$ vim ~/.ssh/config
[http]
proxy = http://192.168.1.101:8888
[https]
proxy = https://192.168.1.101:8888
# [http]
# proxy = socks5://127.0.0.1:1080
# [https]
# proxy = socks5://127.0.0.1:1080

Git Cache

1
2
3
4
5
6
7
# 添加 .gitignore文件之后,可能有些文件报错 `ignored tracked with git`
# 需要用 `git rm --cached`进行删除
$ git rm --cached <file>
# 部分动态文件可能报错文件内容不一致 `the following files have staged content different from both the file and the HEAD`
# 需要增加 `-f`参数进行强制删除
$ git rm --cached -f .idea/workspace.xml

Patch

1
2
$ git diff > patch
$ git apply patch

参考

Code Format

1
2
3
4
5
6
7
8
9
10
11
Intellij Idea
# download: http://www.arminalter.com/public/img/attach/checkstyle/eclipse-java-google-style.xml
File - Settings - Editor - Code Style - Schema - Manage - Import - Eclipse XML Profile
File - Settings - Plugins - "CheckStyle-IDEA"
# download: http://www.arminalter.com/public/img/attach/checkstyle/google_checks.xml
File - Setting - Other Settings - Check Style(+) # 如果这里使用的是 带有变量的 xml文件,需要正确指定对应的 value值
File - Settings - Editor - Inspections - Checkstyle real-time scan(√) # 开启实时 check code style
# 一般的,项目中都会给出 format.xml文件,如 hadoop(hadoop-format.xml) / druid(druid_intellij_formatting.xml) etc.

参考

CI

Travis

.travis.yml

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
33
34
35
language:
- java
- scala
- python
- groovy
os:
- windows
jdk:
- oraclejdk8
scala:
- 2.11.8
python:
- 2.7.12
groovy:
- 2.3.11
before_install: sudo echo "MAVEN_OPTS='-Xmx2048m -Xms1024m -Dorg.slf4j.simpleLogger.defaultLogLevel=error'" > ~/.mavenrc
script:
- mvn clean install -B && mvn clean -B
env:
global:
- MAVEN_OPTS: "-Xmx2048m -Xms1024m -Dorg.slf4j.simpleLogger.defaultLogLevel=error"
sudo: required
cache:
directories:
- $HOME/.m2

Full code is here.

效果图

1
[![Build Status](https://travis-ci.org/asdf2014/yuzhouwan.svg?branch=master)](https://travis-ci.org/asdf2014/yuzhouwan)

Build Status

参考

换行符

Auto CRLF

1
2
3
4
5
6
7
8
# 提交时转换为LF,检出时转换为CRLF
$ git config --global core.autocrlf true
# 提交时转换为LF,检出时不转换
$ git config --global core.autocrlf input
# 提交检出均不转换
$ git config --global core.autocrlf false

Safe CRLF

1
2
3
4
5
6
7
8
# 拒绝提交包含混合换行符的文件
$ git config --global core.safecrlf true
# 允许提交包含混合换行符的文件
$ git config --global core.safecrlf false
# 提交包含混合换行符的文件时给出警告
$ git config --global core.safecrlf warn

Git Bash中文乱码

1
2
3
4
5
6
7
8
9
10
$ git config --global core.quotepath false # 显示 status 编码
$ git config --global gui.encoding utf-8 # 图形界面编码
$ git config --global i18n.commit.encoding utf-8 # 提交信息编码
$ git config --global i18n.logoutputencoding utf-8 # 输出 log 编码
$ export LESSCHARSET=utf-8 # `git log`默认使用 `less`分页,所以需要 `bash`对 `less`命令进行 `utf-8`编码
# 让 `ls`命令可以显示中文名称
$ vim %GIT_HOME%\mingw64\share\git\completion\git-completion.bash
# 在文件末尾处添加一行
alias ls="ls --show-control-chars --color"

资料

Doc

Trick

Emoji

更多资源,欢迎加入,一起交流学习

QQ group: (人工智能 1020982 (高级) & 1217710 (进阶) | BigData 1670647)