Git_note

  1. 1. Git note
    1. 1.1. Git 配置
      1. 1.1.1. 获取升级
      2. 1.1.2. 添加用户信息,并查看配置文件
      3. 1.1.3. 获取帮助
      4. 1.1.4. 生成ssh keys,在Github-keys添加即可
    2. 1.2. Git 基础
      1. 1.2.1. 在现有目录中初始化仓库
      2. 1.2.2. 克隆现有的仓库
      3. 1.2.3. 记录每次更新到仓库
      4. 1.2.4. 忽略文件
      5. 1.2.5. 提交更新
      6. 1.2.6. 移除文件或移动文件
      7. 1.2.7. 查看提交历史
      8. 1.2.8. 撤消操作
      9. 1.2.9. 远程仓库的使用
      10. 1.2.10. 打标签
      11. 1.2.11. 设置别名
    3. 1.3. Git 分支
      1. 1.3.1. 分支的新建和合并
      2. 1.3.2. 分支的管理
      3. 1.3.3. 分支整合之变基
    4. 1.4. Git工具
      1. 1.4.1. 子模块
      2. 1.4.2. 调试
      3. 1.4.3. 维护项目

Git note

学习Git的笔记,完整文档见Git-scm

Git 配置

获取升级

1
$ git clone git://git.kernel.org/pub/scm/git/git.git

添加用户信息,并查看配置文件

1
2
3
$ git config --global user.name "juncaixinchi"
$ git config --global user.email "juncaixinchi111@gmail.com"
$ less ~/.gitconfig

获取帮助

1
2
3
$ git help <verb>
$ git <verb> --help
$ man git-<verb>

生成ssh keys,在Github-keys添加即可

1
2
$ ssh-keygen -t rsa -b 4096 -C "juncaixinchi111@gmail.com"
$ clip < ~/.ssh/id_rsa.pub

Git 基础

在现有目录中初始化仓库

1
$ git init

该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。

1
2
$ git add *
$ git commit -m 'initial project version'

在一个已经存在文件的文件夹(而不是空文件夹)中初始化 Git 仓库来进行版本控制的话,应该开始跟踪这些文件并提交。

克隆现有的仓库

克隆blog-generater至当前目录,分别使用HTTPS协议、SSH协议、本地协议

1
2
3
$ git clone https://github.com/juncaixinchi/blog-generater.git
$ git clone git@github.com:juncaixinchi/blog-generater.git
$ git clone /opt/git/project.git

记录每次更新到仓库

使用命令 git add 开始跟踪跟踪 README 文件

1
$ git add README

检查当前文件状态,加-s为简略信息

1
2
3
$ git status
$ git status -s

忽略文件

创建一个名为 .gitignore 的文件,列出要忽略的文件模式,文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
1
2
# no .a files
*.a
  • 匹配模式可以以(/)开头防止递归。
1
2
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
  • 匹配模式可以以(/)结尾指定目录。
1
2
# ignore all files in the build/ directory
build/
  • 可以使用标准的 glob 模式匹配。
1
2
3
4
5
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory
doc/**/*.pdf

提交更新

commit命令会提交更新,-m参数可添加提交备注,或者随机生成备注 O__O

1
2
$ git commit -m "update"
$ git commit -m "`curl -s http://whatthecommit.com/index.txt`"

给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 add 步骤

1
$ git commit -a -m 'update without git add'

不过正式的提交还是应该避免-m 添加备注,而是详细的添加

移除文件或移动文件

使用 rm 命令将文件从已跟踪文件清单中移除,并连带从工作目录中删除指定的文件,如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

1
2
$ git rm file_to_remove.md
$ git mv file_from file_to

查看提交历史

查看所有log

1
$ git log

显示最近两次提交的差异

1
$ git log -p -2

显示每次提交的简略的统计信息

1
$ git log --stat

以pretty的方式显示提交历史

1
$ git log --pretty=oneline

添加了一些ASCII字符串来形象地展示你的分支、合并历史:

1
$ git log --pretty=format:"%h %s" --graph

只显示作者L在2周内提交的近5条记录

1
$ git log --author L --since=2.weeks -5

撤消操作

尝试重新提交,第二次提交将代替第一次提交的结果

1
2
3
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

取消暂存的文件file_to_cancle.txt(git add 的相反操作)

1
$ git reset HEAD file_to_cancle.txt

撤消对文件的修改,恢复文件file_to_restore.txt到上次提交时候的状态

1
$ git checkout -- file_to_restore.txt

远程仓库的使用

查看远程仓库

1
2
$ git remote -v
$ git remote show

添加远程仓库,默认为 origin

1
2
$ git remote add <shortname> <url>
$ git remote add pd https://github.com/juncaixinchi/blog-generater.git

从远程仓库中抓取,默认从origin抓取,也可自定义

1
2
3
$ git fetch
$ git fetch https://github.com/juncaixinchi/blog-generater.git
$ git fetch origin master:tmp

git fetch不会自动merge,需再merge

1
2
3
$ git fetch origin master:tmp
$ git diff tmp
$ git merge tmp

直接从远程获取最新版本并merge到本地

1
$ git pull origin master

使用 git push (remote) (branch)推送到远程仓库,默认推送到origin/master, 也可自定义远程仓库及分支(如serverfix)

1
2
3
4
$ git push
$ git push https://github.com/juncaixinchi/blog-generater.git
$ git push origin serverfix
$ git push origin serverfix:awesomebranch

设置其他的跟踪分支 - 其他远程仓库上的跟踪分支,或者不跟踪 master 分支

1
$ git checkout --track origin/serverfix

远程仓库的移除和重命名

1
2
$ git remote rm paul
$ git remote rename pb paul

删除远程分支serverfix

1
$ git push origin --delete serverfix

打标签

列出已有标签

1
$ git tag

创建一个附注标签,指定提交的校验和(或部分校验和)则可后期打标签

1
2
$ git tag -a v1.4 -m 'my version 1.4'
$ git tag -a v0.0 -m "origin version" c76e548

共享标签

1
$ git push origin v1.5

设置别名

通过 config 为命令设置别名,外部程序的命令则要加!,使用cmu直接add 及 commit

1
2
3
4
5
6
7
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.st status
$ git config --global alias.last 'log -1 HEAD'
$ git config --global alias.hexo '!hexo g -delpoy'
$ git config --global alias.cmu 'commit -a -m "update"'
$ git config --global alias.logbr 'log --oneline --decorate --graph --all -20'

Git 分支

分支的新建和合并

创建分支testing,分支切换为testing,然后commit内容将在test分支进行

1
2
$ git branch testing
$ git checkout testing

或者在过去某个版本,如593015f,建立分支testing

1
2
3
$ git log --oneline --decorate --graph --all
$ git checkout 593015f
$ git checkout -b testing

使用 log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 –decorate。

1
2
$ git log --oneline --decorate
$ git log --oneline --decorate --graph --all

使用 merge 来合并分支

1
$ git merger testing

如果 master 和 testing 分支都各有提交新版本,则无法自动合并,会出现如下错误,需要手动编辑冲突的文件,然后再 commit,

1
Auto Merge Failed; Fix Conflicts and Then Commit the Result

例如冲突的文件内容为:

1
2
3
4
5
6
7
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> testing:index.html

这表示 HEAD 所指示的版本(也就是你的 master 分支所在的位置)在这个区段的上半部分(======= 的上半部分),而 testing 分支所指示的版本在 ======= 的下半部分。 为了解决冲突,必须选择使用由 ======= 分割的两部分中的一个,或者也可以自行合并这些内容。 例如,通过把这段内容换成下面的样子来解决冲突:

1
2
3
<div id="footer">
please contact us at email.support@github.com
</div>

另外也可以使用图形化工具来解决冲突

1
$ git mergetool

合并完成后删除分支testing

1
$ git branch -d testing

分支的管理

显示分支列表

1
$ git branch

查看每一个分支的最后一次提交

1
$ git branch -v

查看已经合并或尚未合并到当前分支的分支

1
2
$ git branch --merged
$ git branch --no-merged

删除和强制删除分支

1
2
$ git branch -d testing
$ git branch -D testing

分支整合之变基

使用 rebase 命令将提交到某一分支 testing 上的所有修改都移至另一分支 master 上,然后回到 master 分支,进行一次快进合并。

1
2
3
4
5
$ git checkout testing
$ git rebase master
$ git checkout master
$ git merge testing

直接将特性分支(testing)变基到目标分支(即 master)上

1
$ git rebase master testing

对两个分支进行变基时,将 client 中的修改合并到主分支并发布,但暂时并不合并 server 中的修改

1
$ git rebase --onto master server client

变基的风险:不要对在仓库外有副本的分支执行变基

Git工具

子模块

将一个已存在的 Git 仓库添加为正在工作的仓库的子模块。

1
2
3
4
$ git submodule add git@github.com:juncaixinchi/hexo-theme-next.git themes/next
$ git submodule init
$ git submodule update
$ git submodule update themes/next

在开始克隆含有子模块的仓库时,可添加–recursive,直接递归添加所有子模块

1
$ git clone --recursive https://github.com/juncaixinchi/blog-generater.git

让 Git 在推送到主项目前检查所有子模块是否已推送

1
$ git push --recurse-submodules=check

让 Git 自动进入到子模块中,然后在推送主项目前推送了它

1
$ git push --recurse-submodules=on-demand

遍历子模块运行命令

1
$ git submodule foreach 'git push'

调试

通过自动进行一个二分查找来找到哪一个特定的提交是导致 bug 或者问题的第一个提交。

开始二分查找,并设置当前版本为有问题状态

1
2
$ git bisect start
$ git bisect bad

设定没有问题的版本,然后依次检测个版本,设定 bad or good ,直到找到问题版本

1
$ git bisect good v1.0

完成后,重置 HEAD 指针到最开始的位置

1
$ git bisect reset

标注任何文件的行,指出文件的每一行的最后的变更的提交及谁是那一个提交的作者,通过-L来限定行数

1
2
3
$ git blame
$ git blame -L 12,22 file_to_check

在源代码中,甚至是你项目的老版本中的任意文件中查找任何字符串或者正则表达式

1
$ git grep

维护项目

balabala…