学习廖雪峰老师的Git教程的简单记录,主要是命令的汇总。
Git 是目前世界上最先进的分布式版本控制系统(没有之一)。自动记录每次文件改动,还可以让同事协作编辑。
- 1991年,Linus 创建了全世界志愿者共同参与的开源系统软件 Linux,这些志愿者将源代码通过 diff 的方式发送给 Linus,然后由 linus 本人手工方式合并代码,Linus 坚定反对使用速度慢且必须联网的 CVS 和 SVN,以及违背开源精神的其他付费商用版本控制系统;
- 2002年,鉴于随着 Linux 发展其代码库太大,同时社区弟兄的不满,Linus 选择了一个商业的版本控制系统 Bitkeeper,其东家 BitMover 出于人道主义授权 Linux 社区免费使用;
- 2005年,随着 Liunx 社区的牛人聚集,开发 Samba 的 Andrew 试图破解 BitKeeper 的协议被 BitMover 发现,收回免费授权;
- 于是 Linus 花了两周时间自己用 C 写了一个分布式的版本控制系统,这就是 Git,一个月之内,Linux 系统的源代码已经由 Git 管理了;
- 之后 Git 迅速成为最流行的分布式版本控制系统,尤其是2008年随着 GitHub 的上线,它为开源项目免费提供 Git 储存,无数项目开始迁移至 GitHub,如 jQuery、PHP、Ruby等。
- 集中式,版本库存放在中央服务器,每次工作先要用自己电脑从中央服务器获取最新版本,集中式最大毛病是必须联网才能工作,如 CVS、SVN;
- 分布式,不存在“中央服务器”(虽然有一个充当的,但是作用仅是方便大家“交换”修改,没有它也可以工作),每个电脑都是一个完整版本库,工作不需联网,比集中式安全,如 Git;
Git 较于 SVN 等还有其他优势,如极其强大的分支管理等;其他集中式,如 IBM 的 ClearCase,微软的 VSS;其他分布式,如 Mercurial 和 Bazaar 等。但 Git 是最快、最简单也是最流行。
- Linux,部分系统自带,否则通过
$ sudo apt-get install git即可安装; - Mac:
- 先安装 homebrew,再通过其安装 Git;
- 推荐方法,直接从 AppStore 安装 Xcode,其集成了 Git(不过还需在其 Preference 中 Downloads,并 Install)。
- Windows,Git 官网下载,按默认安装即可。
设置 username:$ git config --global user.name "Your name"
设置 useremail:$ git config --global user.email "email@example.com"
上述二者冒充可查,--global 表示在这台机器上的所有仓库都会使用这个配置,当然也可不同仓库指定不同用户名和邮箱地址。
版本库,简单理解为一个目录,里面所有文件可以被 Git 管理,每个文件的修改、删除都能被跟踪,可以追踪历史、还原等,又叫仓库、repository。
初始化仓库:$ git init
将文件添加到仓库,分两步(第一步可多次使用):
-
$ git add <file> -
$ git commit -m <message>
查看仓库当前状态:$ git status
查看提交日志:$ git log( --pretty=oneline),由近及远
回退到上一个版本:$ git reset --hard HEAD^,HEAD指当前版本,^个数表示回退个数,或 $ git reset --hard ~n 回退到倒数第n个
回退到某一个版本:$ git reset --hard <commit_id>,向前向后都行
查看记录的每一次命令:$ git reflog
- 工作区,Working Directory,电脑能看到的文件夹;
- 版本库,Repository,隐藏的 .git 文件夹,包括暂存区(又称 stage 或 index)和 Git 自动为我们创建的第一个分支 master,以及指向 master 的指针 HEAD,前文“将文件添加到仓库”的两步分别如图所示。
查看修改内容:
$ git diff,比较工作区和stage;$ git diff --cached,比较stage和index;$ git diff HEAD,比较工作区和index;
Git 比其他版本控制系统设计得优秀的一个原因,是因为 Git 跟踪并管理的是修改,而非文件。
如果“第一次修改 -> git add -> 第二次修改 -> git commit”,则第二次修改不会被提交,即每次修改,如果不用 git add 到暂存区,那就不会加入到 commit 中。
撤销工作区全部修改:$ git checkout -- <file>,让 file 回到最近一次 add/commit 时状态:
- 如果 file 修改后没有 add,则撤销到和版本库一样;
- 如果 file 已经 add 后又修改,则撤销到和 add 后的状态。
撤销暂存区全部修改:$ git reset HEAD <file>,HEAD 表示最新的版本,详见 “git reset --help”
删除文件:$ git rm <file>
- “git add -> git commit -> rm -> git rm -> git commit”,如果 “rm” 是误删,可及时通过 “git checkout -- file” 从 stage 恢复;
- “git add -> git commit -> git rm -> git commit”,如果 “git rm” 是误删,则 stage 中也被删,可及时先通过 “git reset HEAD file” 撤销暂存区修改,再通过 “git checkout -- file” 从 stage 恢复;
注册 GitHub,并进行两步设置:
- 创建SSH keys:
$ ssh-keys -t rsa -C "youremail@example.com",会在主目录下生成一对密钥对:id_rsa 和 id_rsa_pub,前者是私钥,不能泄露,后者是公钥,可以告诉他人; - 登录 GitHub 添加公钥,“ setting -> SSH and GPG keys”。
步骤:
- GitHub 网站 “create a new repo”,设置仓库名 repo_name;
$ git remote add origin git@github.com:<github_name>/<repo_name>.git;- 将本地提交推到远程:
$ git push origin master,第一次需要使用$ git push -u origin master将本地 master 分支和远程 master 分支关联。
Git 支持多种协议,默认的 "git://" 使用 ssh,也可以使用 https(速度慢,且每次推送需要输入口令)等其他协议:
git clone git@github.com:<github_name>/<repo_name>.gitgit clone https://github.com/<github_name>/<repo_name>.gitgit clone git://github.com/<github_name>/<repo_name>.git
分支:Git 将每次提交串成的一条时间线。目前为止只有默认的 master 主分支。
查看当前分支:$ git branch
创建分支:$ git branch <branch_name>
切换分支:$ git checkout <branch_name>
创建同时切换至新分支:$ git checkout -b <branch_name>,等同上述二者
合并某分支到当前分支:$ git merge <branch_name>
删除分支:$ git branch -d <branch_name>
如上图,如果 master 分支和 feature1 分支都有更新,则 merge 二者可能会报冲突,这时可以通过 git status 查看冲突,并手动解决冲突,再提交,最后合并。可以通过 “git log --graph( --pretty=oneline --abbrev-commit)” 查看分支合并图。
使用 no-ff 方式合并分支:git merge --no-ff -m <message> <branch_name>",可以保留分支信息,“git merge” 默认的 fast froward 模式不会保留分支信息。
实际开发分支管理原则:
- master 分支:非常稳定的,仅用来发布新版本;
- dev 分支:不稳定的,日常干活的分支;
- 每个人有各自分支,不时往 dev 分支合并。
修复 bug 时,我们会通过创建新的分支进行修复,修复好后进行合并,并删除。如果手头工作还没有完成,可以在手头分支把工作现场储存起来。
储存工作现场:$ git stash
查看 stash 列表:$ git stash list
恢复到工作现场,方式1:$ git stash pop,恢复同时也删除该 stash
恢复到工作现场,方式2:
- 恢复到指定 stash:
$ git stash apply stash@{n}; - 删除 stash 内容:
$ git stash drop。
实际开发中,每添加一个新功能最好新建一个 feature 分支。
- 顺利的话,和 bug 分支类似,合并然后删除;
- 需要放弃 feature,则使用 “git branch -d branch_name” 删除,对于未合并过的分支需要使用 D 替代 d,且删后找不回。
查看远程库信息:$ git remote( -v),括号内表示查看详细信息
从远程抓取分支:$ git pull,有冲突需先解决
多人协作通常工作模式:
- 首先,试图 “git push origin bransh_name” 推送自己修改;
- 若推送失败,则是因为远程分支比你的本地更新,需要先通过 “git pull” 试图合并;
- 若合并有冲突,则先解决冲突,并在本地提交;
- 不存在冲突后,再利用 “git push origin branch_name”推送。
建立本地分支和远程分支链接:$ git branch --set-upstream-to=origin/<branch_name> <branch_name>,解决 “git pull” 时可能会出现的 “no tracking infromation”。
将本地未 push 的分支提交历史整理成直线:$ git rebase,便于查看历史提交的变化,缺点是本地的分支提交已经被修改过了。
标签:tag,版本库快照,实际是指向某个 commit 的指针(和分支很像,但是标签不能移动),唯一确定打标签时刻的版本。
标签总是与某个 commit 挂钩,如果这个 commit 出现在多个分支,则这些分支上都会看到这个 tag。
新建默认标签:$ git tag <tag_name>,默认 HEAD
新建指定标签:$ git tag -a <tag-name> -m <message> <commit_id>,指定 commit_id 打标签,并附 message 说明文字
查看指定名称标签:$ git show <tag_name>
查看所有标签:$ git tag
推送本地标签到远程:$ git push origin <tag_name>
一次性推送所有标签:$ git push origin --tags
删除标签:$ git tag -d <tag_name>
删除远程标签,分两步:
- 先删除本地,同上;
- 删除远程:
git push origin :refs/tags/<tag_name>
-
在 GitHub 上,可以任意 Fork 开源仓库;
-
自己拥有 Fork 后的仓库的读写权限;
-
可以推送 pull request 给官方仓库来贡献代码。
码云:国内 Git 托管服务,较 GitHub 网速快很多。
和GitHub相比,码云也提供免费的Git仓库。此外,还集成了代码质量检测、项目演示等功能。对于团队协作开发,码云还提供了项目管理、代码托管、文档管理的服务,5人以下小团队免费。
删除关联的远程库:git remote rm origin
通过 “git remote add gitee git@gitee.com:<gitee_name>/<repo_name>.git”、“git remote add github git@github.com:<github_name>/<repo_name>.git”,Git 可以同时同步到多个远程库:
在安装 Git 一节中,我们已经配置了 user.name 和 user.email,实际上,Git还有很多可配置项。
显示颜色:$ git config --global color.ui true
在 Git 工作区的根目录下创建一个特殊的 .gitignore 文件,然后把要忽略的文件名填进去,Git 就会自动忽略这些文件。Windows 下,不能直接以这个文件名创建文件,可以通过文本编辑器中“保存”或“另存为”来解决。
我们不需要从头写 .gitignore 文件,GitHub 已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore。
忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等;
- 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
强制添加忽略文件到 Git:$ git add -f <file>
查找限制文件的规则:$ git check_ignore -v <file>
配置命令别名:$ git config --global alias.<command_alias> command,如:
- “ git config --global alias.st status”,则以后 “git st” 等价于 “git status”;
- “ git config --global alias.unstage “reset HEAD””,则以后 “git unstage file” 等价于 “git reset HEAD file”。
上述设置的配置文件是位于工作区目录的 .git/config 文件;如果不设置 global 参数,则设置仅对当前仓库有效,配置文件是位于主目录的 .gitconfig 文件。对于二者,均是删除对应行即删除别名。
步骤:
- 安装 Git:
$ sudo apt-get install git - 创建运行用户:
$ sudo adduser git - 创建证书登陆:收集所有需要登录的用户的公钥,就是他们自己的 id_rsa.pub 文件,把所有公钥导入到 /home/git/.ssh/authorized_keys 文件里,一行一个
- 初始化仓库:
- 先选定目录,如 /srv/sample.git,进行初始化,建立裸仓库(纯粹为共享),
$ sudo git init --bare sample.git - 更改权限,将 owner 改为 git,不让用户直接登陆到服务器上改工作区(服务器上仓库通常以 .git 结尾):
$ sudo chown -R git:git sample.git
- 先选定目录,如 /srv/sample.git,进行初始化,建立裸仓库(纯粹为共享),
- 禁用 shell 登陆,出于安全考虑,第二步创建的 git 用户不允许登录 shell ,这可以通过编辑 /etc/passwd 文件的以下行完成:“git:x:1001:1001:,,,:/home/git:/bin/bash” -> “git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell”
- 克隆远程仓库:
$ git clone git@server:/srv/sample.git
Gitosis是一个可以方便管理密钥和管理权限的工具。






