文章目录
置顶
- 有必要把git整理一下了
一、起步
1. 配置
- 用户信息
$ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com
- 远程提交时,commit的用户一定要有远程提交的权限,之前我就是这个问题,一直提交不了
- 文本编辑器
git config --global core.editor "\"D:\应用程序\Sublime Text3\sublime_text.exe\"" $ git config --global core.editor emacs/vim
- 修改config文件
//...略 [core] editor = \"D:\\应用程序\\Sublime Text3\\sublime_text.exe\"
- 检查配置信息
$ git config --list user.name=John Doe user.email=johndoe@example.com color.status=auto color.branch=auto color.interactive=auto color.diff=auto ...
2. license
二、git基础
1. 获取 Git 仓库
- 本地初始化
//在项目目录 git init git add . git commit -m "信息"
- 克隆现有的仓库
- 当你执行 git clone 命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。
- 从github上clone项目
git clone https://github.com/xtlvlv/Algorithm.git newname //newname是自定义本地仓库名,可以省略
- 也可以自己在服务器搭建git,详见第四章。
2. 记录每次更新到仓库
- 检查当前文件状态
git status git status -s //更简洁的查看
- 跟踪新文件
git add README
- 这个也用于暂存修改
- 若一个文件git add后,又修改了,commit时提交的是修改前的状态,必须再次git add
- 忽略文件
- 创建一个名为 .gitignore 的文件,列出要忽略的文件模式。例如
$ cat .gitignore *.[oa] //忽略所有以.o或.a结尾的文件 *~ //忽略所有~结尾的文件
- 文件 .gitignore 的格式规范如下:
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
- 查看已暂存和未暂存的修改
- 当git add 后又修改了文件,git status就会显示已暂存和未暂存的文件
- 查看都修改了哪些
git diff
- 提交更新
git commit //这种方式会启动文本编辑器以便输入本次提交的说明。 git commit -m "说明" //简短说明,快速提交
- 跳过使用暂存区域
git commit -a
- 这种方式 Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
- 移除文件
git rm README
- 移动文件
- 改名
git mv file_from file_to //等价于 $ mv README.md README $ git rm README.md $ git add README
3. 查看提交历史,git log
- 常用
git log git log -g -2
- -p 用来显示每次提交的内容差异。 加上 -2 仅显示最近两次提交
- 每次提交的简略的统计信息,你可以使用 --stat 选项
git log --stat
- 输出限制
- 用时查文档吧
4. 撤消操作
- 重新提交
git commit --amend
- 若git commit 后没有做任何修改,执行这条命令没有改变
- 若git commit 后修改了,执行这条命令改变之前的提交,不是重新提交,也就是只有一条提交记录
- 取消暂存的文件
git reset HEAD README.md
- 把 README.md 从暂存区取消,commit时就不会提交这个文件
- 撤消对文件的修改
git checkout -- README.md
- 可以将 README.md 还原成上次提交时的样子
- git checkout – [file] 是一个危险的命令,这很重要。 你对那个文件做的任何修改都会消失 - 你只是拷贝了另一个文件来覆盖它。 除非你确实清楚不想要那个文件了,否则不要使用这个命令。
- 在 Git 中任何 已提交的 东西几乎总是可以恢复的。 甚至那些被删除的分支中的提交或使用 --amend 选项覆盖的提交也可以恢复。 然而,任何你未提交的东西丢失后很可能再也找不到了。
5. 远程仓库的使用,git remote
- 查看远程仓库
git remote //如果是clone下来的,至少有个origin $ git remote -v //显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL bakkdoor https://github.com/bakkdoor/grit (fetch) bakkdoor https://github.com/bakkdoor/grit (push) cho45 https://github.com/cho45/grit (fetch) cho45 https://github.com/cho45/grit (push) defunkt https://github.com/defunkt/grit (fetch) defunkt https://github.com/defunkt/grit (push) koke git://github.com/koke/grit.git (fetch) koke git://github.com/koke/grit.git (push) origin git@github.com:mojombo/grit.git (fetch) origin git@github.com:mojombo/grit.git (push)
- 添加远程仓库
$ git remote add pb https://github.com/paulboone/ticgit $ git remote -v origin https://github.com/schacon/ticgit (fetch) origin https://github.com/schacon/ticgit (push) pb https://github.com/paulboone/ticgit (fetch) pb https://github.com/paulboone/ticgit (push)
- pb 代表URL的简写
- 从远程仓库中抓取与拉取
- git fetch [remote-name]
- 这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。
$ git fetch pb
- 如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作。
- git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。
- 如果你有一个分支设置为跟踪一个远程分支,可以使用 git pull 命令来自动的抓取然后合并远程分支到当前分支。默认情况下,git clone 命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或不管是什么名字的默认分支)
- 推送到远程仓库
- git push [remote-name] [branch-name]
$ git push origin master //克隆时通常会自动帮你设置好这两个名字
- 只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。
- 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。
- 查看远程仓库
- git remote show [remote-name]
$ git remote show origin
- 远程仓库的移除与重命名
- 重命名
$ git remote rename pb paul $ git remote origin paul
- 移除
$ git remote rm paul $ git remote origin
6. 打标签,git tag
- 列出标签
git tag
- 创建标签
- 轻量标签(lightweight)
轻量标签本质上是将提交校验和存储到一个文件中,没有保存任何其他信息。 创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字:
$ git tag v1.4-lw $ git tag v1.4-lw
- 附注标签(annotated)
附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。 通常建议创建附注标签,这样你可以拥有以上所有信息;
$ git tag -a v1.4 -m 'my version 1.4' $ git tag v1.4 //查看标签信息与对应的提交信息 $ git show v1.4 tag v1.4 Tagger: Ben Straub <ben@straub.cc> Date: Sat May 3 20:19:12 2014 -0700 my version 1.4 ......
- 对过去的提交打标签
//查看历史 $ git log --pretty=oneline 9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo //加标签 $ git tag -a v1.2 9fceb02
- 轻量标签(lightweight)
- 共享标签
- 默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样 - 你可以运行 git push origin [tagname]。
$ git push origin v1.5 $ git push origin --tags //把所有不在远程仓库服务器上的标签全部传送到那里。
- 删除标签
git tag -d v1.4-lw //加上 -d 删除,但不会更新远程仓库的
- 远程仓库移除标签
//git push <remote> :refs/tags/<tagname> $ git push origin :refs/tags/v1.4-lw
- 检出标签
$ git checkout 2.0.0
三、git分支
1. 分支简介
- 分支创建
$ git branch testing
- Git 又是怎么知道当前在哪一个分支上呢?
它有一个名为 HEAD 的特殊指针。在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。
- Git 又是怎么知道当前在哪一个分支上呢?
- 分支切换
$ git checkout testing
- HEAD就会指向testing,此时做的更改是在testing分支上,HEAD一直跟着testing,切换为master的话就会回到之前的分支
- 查看各个分支当前所指的对象
$ git log --oneline --decorate
2. 分支的新建与合并,git checkout
- 新建分支
$ git checkout -b iss53 //并将HEAD指向iss53, 等价于 $ git branch iss53 $ git checkout iss53
- 删除分支
$ git branch -d hotfix
- 合并分支
- 要先移动到被合并的分支,比如想把hotfix合并到master上,要先移动到master分支上
$ git checkout master $ git merge hotfix
- 不同的合并情况
- 快进合并:master和hotfix在一条线上,只是把master往前移动到hotfix上
- 分叉合并: master和hotfix不在一条线上,复杂一些
- 遇到冲突时的分支合并
- 如果在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。
- 若遇到冲突后,只能把冲突解决才能合并,即把连个分支都修改的某个文件,变为相同的修改
3. 分支管理,git branch
- 查看分支
$ git branch iss53 * master //表示当前在这个分支上 testing
- 查看每一个分支的最后一次提交
$ git branch -v
- 要查看哪些分支已经合并到当前分支
$ git branch --merged iss53 //表明iss53已经合并到master,可以删除了 * master
- 在这个列表中分支名字前没有 * 号的分支通常可以使用 git branch -d 删除掉;已经将它们的工作整合到了另一个分支,所以并不会失去任何东西。
- 查看所有包含未合并工作的分支
$ git branch --no-merged testing
- 删除未合并的分支会失败
$ git branch -d testing error: The branch 'testing' is not fully merged. If you are sure you want to delete it, run 'git branch -D testing'.
4. 远程分支,git fetch push pull
- 更新远程仓库引用
- 如果git clone之后,自己做了一些修改后commit后,本地就会领先远程分支,这时万一有其他人提交远程分支了,在clone那个节点就出现了分叉
- 这时可以用git fetch拉去远程更新的分支,变成本地的一个分支,合并后再提交
git fetch origin
- 推送
- 推送到有写入权限的远程仓库
- git push (remote) (branch)
$ git push origin serverfix
- 这里有些工作被简化了。 Git 自动将 serverfix 分支名字展开为 refs/heads/serverfix:refs/heads/serverfix,那意味着,“推送本地的 serverfix 分支来更新远程仓库上的 serverfix 分支。”
- 跟踪分支
- 跟踪分支是与远程分支有直接关系的本地分支。 如果在一个跟踪分支上输入 git pull,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。
- 当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支。
- 创建跟踪分支
$ git checkout -b sf origin/serverfix Branch sf set up to track remote branch serverfix from origin. Switched to a new branch 'sf' //现在,本地分支 sf 会自动从 origin/serverfix 拉取。
- 修改正在跟踪的上游分支
$ git branch -u origin/serverfix Branch serverfix set up to track remote branch serverfix from origin.
-
- git pull
- git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个 git merge 命令
- 由于 git pull 的魔法经常令人困惑所以通常单独显式地使用 fetch 与 merge 命令会更好一些。
-
- 删除远程分支
$ git push origin --delete serverfix To https://github.com/schacon/simplegit - [deleted] serverfix
- 基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。
5. 变基rebase
- 和合并merge功能一样
- 无论是通过变基,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。 变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。
- 合并merge好还是变基rebase好?
- 总的原则是,只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作
- rebase的使用
$ git checkout experiment $ git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command //先rebase,然后再合并,这里的合并只是移动指针,如果不变基就合并的话,要做的工作更多 $ git checkout master $ git merge experiment
- 这两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。 你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的,但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。
四、服务器上的git
- 可以自己建立git服务器,但现在用好github就行了,以后需要的时候再说
之后
- 后面的略览了一下,使用基本的git,以上就够了,后面先不看了,有需要再说吧。