Git 基础使用
目录
1 前言
使用 Git
也有一段时间了, 最初只是随便找了一个教程看了一下, 便将就着用了。
遇到问题 Google
一下, 也基本能解决问题。 但还是感觉有必要重新回顾一下基础了。
不说详细了解 Git
的低层, 但至少希望能对 Git
的使用有更近一层的了解。
幸运的是, Git
有一份中文版的 Git-Book. 这让我的学习更加容易。
本篇博客的内容主要是 Git-Book
前三章内容的笔记和理解。
2 基本概念
Git
项目有三个工作区域, 分别对应了三种状态:
- 工作目录: 对应状态 已修改
modified
- 暂存区域: 对应状态 已暂存
staged
- Git 仓库: 对应状态 已提交
committed
平时, 我们对文件的操作都发生在 工作目录, 当我们对文件作出修改时, 工作目录 中的内容就和 Git 仓库 中对应版本的内容出现的区别。
这时, 修改过后的文件的状态就变成的 modified
.
对于需要 提交 的文件, 我们会使用 git add
指令对其进行标记。 标记过的文件的状态会变为 staged
.
这时, 这些文件的 快照 就保存在了 暂存区域 中。
然后, 使用 git commit
指令将 暂存区域 的文件保存的 Git 仓库 的数据库中。
这时, 文件状态变为 committed
.
3 配置 Git
配置 这个问题不是问题, 很多教程都对初步使用 Git
需要进行配置进行了详细的解说。
所以, 这里就简单的记录一下就 OK 了。
First, 是配置文件的位置:
/etc/gitconfig
: 包含系统上每一个用户及他们仓库的通用配置, 使用git config --system
读写~/.gitconfig
或~/.config/git/config
: 只针对当前用户, 使用git config --global
读写.git/config
: 针对当前仓库, 使用git config
读写
每一个级别覆盖上一级别的配置, 所以 .git/config
的配置变量会覆盖 /etc/gitconfig
中的配置变量。
对于 Windows
, Git
会查找 $HOME(C:\Users\$USER)
目录下的 .gitconfig
文件。
Second, 是用户信息的配置:
$ git config --global user.name "xxx xxx"
$ git config --global user.email xxx@example.com
这应该是最常用的配置, 配置好就可以开始使用了 Git
了。
Then, 配置默认的文本编辑器:
$ git config --global core.editor xxx
文本编辑器的配置是很有用的, 如果你使用 git commit
指令进行提交, 又有一份很好的提交模板。
我的设置是 Gvim
, 毕竟是 Windows
系统, vim
在命令行里面实在是不好看。
Finally, 检查配置信息:
# 列出所有配置 $ git config --list # 检查 Git 的某一项配置 $ git config <key>
4 常用指令
Git
有着很多的指令, 对于不清楚功能的指令, 可以通过 git help <cmd>
的方式来获取帮助。
# 初始化仓库 $ git init # 克隆远程仓库 $ git clone <url> # 可以命名克隆到本地后文件夹的名称 $ git clone <url> <name> # 检查文件状态 $ git status # 添加文件到暂存区 - 支持 glob 语法 $ git add <name> # 添加所有文件 $ git add --all # 查看 未暂存 文件做的修改 $ git diff # 查看 已暂存 文件做的修改 $ git diff --cached # 提交更新, 并启动编辑器编写注解 $ git commit # 不启动编辑器 $ git commit -m "xxx" # 跳过 git add $ git commit -a # 移除文件 - 类似于 rm 指令 $ git rm # 移动/重命名文件 - 类似于 mv 指令 $ git mv file_from file_to # 查看提交历史 $ git log # 设置命令别名 -- xx 就是 <cmd> 的别名 $ git config --global alias.xx <cmd>
4.1 忽略文件
通过 .gitignore
文件列出需要忽略的文件, 这些文件不会纳入 Git
的管理。
.gitignore
文件支持 glob 语法。
另外, 子目录的 .gitignore
文件可以覆盖父目录的 .gitignore
设置。 这在某些时候会很有用。
4.2 常用别名设置
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
5 撤销操作
人总是会犯错的, 而 Git
允许我们对做错了的事进行弥补。
- 重新提交
运行带有
--amend
选项的提交命令可以尝试重新提交, 例如提交后发现忘记了暂存某些需要的修改, 可以像下面这样操作:$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend
最终只会有一个提交 - 第二次提交将代替第一次提交的结果。
- 取消暂存的文件
使用
git reset HEAD <file>...
来取消暂存的文件。$ git reset HEAD README.md
- 撤消对文件的修改
使用
git checkout -- <file>
将文件还原为上一次提交的状态。$ git checkout -- README.md
6 远程仓库
远程仓库 是一个好东西, push
之后感觉都会安全不少。
- 查看远程仓库
git remote
列出你指定的每一个远程服务器的简写,git remote -v
显示需要读写远程仓库使用的Git
保存的简写与其对应的URL
- 添加远程仓库
- 运行
git remote add <shortname> <url>
添加一个新的远程Git
仓库,同时指定一个可以轻松引用的简写。 - 从远程仓库中抓取与拉取
执行
git fetch [remote-name]
访问远程仓库,从中拉取所有还没有的数据。如果使用
clone
命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以origin
为简写。如果一个分支设置为跟踪一个远程分支,可以使用
git pull
命令来 自动 的抓取然后合并远程分支到当前分支。- 推送到远程仓库
- 简单直接:
git push [remote-name]
- 查看远程仓库
- 看某一个远程仓库的更多信息,可以使用
git remote show [remote-name]
命令 - 远程仓库的移除与重命名
- 运行
git remote rename
修改一个远程仓库的简写名, 使用git remote rm
移除一个远程仓库。
7 打标签
对某个特定版本打标签是很有用的。
- 列出标签
- 列出所有标签使用
git tag
. - 创建标签
有两种标签:
# 创建附注标签, git show 可以看到信息 $ git tag -a version -m "commnet" # 创建轻量标签 $ git tag version
- 后期打标签
- 可以对过去的提交打标签,
git tag -a version 9fceb02
. 9fceb02 是过去提交的部分校验和。 - 共享标签
- 将标签上传到远程服务器。 运行
git push origin [tagname]
, 带有--tags
选项的git push
命令会把所有不在远程仓库服务器上的标签全部传送到那里。 - 检出标签
- 使用
git checkout -b [branchname] [tagname]
在特定的标签上创建一个新分支。 - 删除标签
- 打错标签可以通过
git tag -d version
来删除标签。
PS: 前段时间发现 Github
会根据 tag
自动生成 release
.
8 分支
Git
中的分支操作很方便, 同时分支也是一个很重要的功能。 新的想法可以通过一个临时分支来进行尝试。 如果尝试效果很好便可以将分支合并到主分支, 不好也可以直接删除分支,不影响主分支的工作。
8.1 概念
首先, 是 提交对象 这一概念。 每一次提交都会创建一个 提交对象. 这个提交对象可以代表仓库此时的状态。
每一个 提交对象 都包含一个指向前一个 提交对象 的指针(即父对象)。 第一个提交没有父对象。
而 分支, 就是指向一个 提交对象 的指针。 而当前分支就是 HEAD
指针指向的分支。
创建分支的过程就是创建一个指向某 提交对象 的指针。 而切换分支就是将 HEAD
指针的指向切换到指定的分支。
这样, 一连串的提交形成一个有 提交对象 组成的 链表, 不同分支上的工作又使这个 链表 出现分叉。
8.2 操作
分支的基本操作很简单:
# 新建分支 $ git branch <name> # 获取当前分支列表 $ git branch # 检查每一个分支最后的提交 $ git branch -v # 滤列表中 合并/未合并 到当前分支的分支 $ git branch --merged/--no-merged # 切换分支 $ git checkout <name> # 新建并切换 $ git checkout -b <name> # 合并分支 $ git merge <name> # 删除分支 $ git branch -d <name>
如果合并分支时遇到冲突, 可以使用 git mergetool
来帮助解决冲突问题。
8.3 远程分支
远程分支不等于当前分支.
很多时候, 由于远程分支和当前分支的同步行为, 总是认为 远程分支 和 当前分支 是一样的。
但是,实际上两者是有区别的。
origin/master
和 master
不一定是指向同一个 提交对象.
当远程分支更新后, 需要通过 git fetch
命令将更新拉取到本地。
这时 origin/master
和 master
指向的提交对象会出现区别甚至分叉。 需要运行 git merge
指令同步更新。
git pull
指令可以自动完成 git fetch
和 git merge
指令。
- 跟踪分支
如果在一个跟踪分支上输入
git pull
,Git
能自动地识别去哪个服务器上抓取、合并到哪个分支设置其他跟踪分支:
# 跟踪分支, branch 的名称可以和远程分支的不同 $ git checkout -b [branch] [remotename]/[branch] # 快捷方式, 名称相同 $ git checkout --track [remotename]/[branch]
设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支,可以在使用
-u
或--set-upstream-to
选项运行git branch
来显式地设置$ git branch -u origin/serverfix
通过这样的方式可以获取远程分支但不会跟踪:
$ git checkout -b [branch] $ git pull [remote] [branch] # 获取远程分支内容但不跟踪 $ git push [remote] [branch] # 任然可以将更新推送到远程分支
- 删除远程分支
运行带有
--delete
选项的git push
命令来删除一个远程分支(从服务器删除)$ git push origin --delete serverfix
8.4 变基
这不是一个好名字。
- 变基: 提取在一个分支中引入的补丁和修改, 然后在另一个分支的基础上应用一次。
变基的概念很清楚, 操作上也很方便:
# 切换到要提取修改的分支 $ git checkout <branch> # 将修改应用到目标分支 $ git rebase <branch>