原创 澳明 阿里技术
阿里技术
微信号ali_tech
功能介绍阿里巴巴官方技术号,关于阿里的技术创新均呈现于此。
阿里妹导读:相信大部分开发者对 Git 都不陌生,G it 也已成为大部分开发者日常开发必用的工具。本文分享 Git 使用上的一些基础知识,通俗 易懂,非常有 用。
没接触过:平时接触的代码还托管在 SVN 或 CVS 等工具上。
不太熟悉:可能对 Git 的使用还不太熟悉和全面,导致了在使用 git 时步步为营。
Never Be Afraid To Try Something New.
Who:是谁执行的变更?
When:什么时候做出的变更?
What:这次变更做了什么事情?
你可以看到我的变更提交。
我也可以看到你的变更提交。
如果双方都进行了变更提交,也可以以某种方式方法进行比对和合并,最终作出统一的变更版本。
提交对象(git commit object):每一个提交在 Git 中都通过 git commit object 存储,对象具有一个全局唯一的名称,叫做 revision hash。它的名字是由 SHA-1 算法生成,形如"998622294a6c520db718867354bf98348ae3c7e2",我们通常会取其缩写方便使用,如"9986222"。
$ git init hackers $ cd hackers $ git status
➜ hackers git:(master) git status On branch master No commits yet nothing to commit (create/copy files anduse "git add" to track)
1)output 1: On branch master
2)output 2:No commits yet
nothing to commit (create/copy files anduse "git add" to track)
工作区:工作区指的是我们本地工作的目录,比如我们可以在刚才创建的 hackers 目录下新增一个 readme 文件,readme 文件这时只是本地文件系统上的修改,还未存储到 Git。
暂存(索引)区:暂存实际上是将我们本地文件系统的改动转化为 Git 的对象存储的过程。
仓库: git commit 后将提交对象存储到 Git 仓库。
This command updates the index using thecurrent content found in the working tree, to prepare the content stagedfor the next commit.
It typically adds the current content ofexisting paths as a whole, but with some options it can also be used toadd content with only part of the changes made to the working tree filesapplied, or remove paths that do not exist in the working tree anymore.
The "index" holds a snapshot ofthe content of the working tree, and it is this snapshot that is taken as thecontents of the next commit.
Thus after making any changes to theworking tree, and before running the commit command, you must use the addcommand to add any new or modified files to the index.
通过 git add 命令将改动暂存。
可以使用 git add -p 来依次暂存每一个文件改动,过程中我们可以灵活选择文件。中的变更内容,从而决定哪些改动暂存。
如果 git add 不会暂存被 ignore 的文件改动。
通过 git rm 命令,我们可以删除文件的同时将其从暂存区中剔除。
通过 git reset 命令进行修正,可以先将暂存区的内容清空,在使用 git add -p 命令对改动 review 和暂存。
这个过程不会对你的文件进行任何修改操作,只是 Git 会认为目前没有改动需要被提交 。
如果我们想分阶段(or 分文件)进行 reset,可以使用 git reset FILE 或 git reset -p命令。
可以用 git diff --staged 依次检查暂存区内每一个文件的修改。
用 git diff 查看剩余的还未暂存内容的修改。
当你对需要修改的内容和范围满意时,你就可以将暂存区的内容进行 commit 了,命令为: git commit 。
如果你觉得需要把所有当前工作空间的修改全部 commit,可以执行 git commit -a ,这相当于先执行 git add 后执行 git commit ,将暂存和提交的指令合二为一,这对于一些开发者来说是很高效的,但是如果提交过大这样做通常不合适。
我们建议一个提交中只做一件事,这在符合单一职责的同时,也可以让我们明确的知道每一个 commit 中做了一件什么事情而不是多个事情。所以通常我们的使用习惯都是执行 git add -p 来 review 我们将要暂存内容是否合理?是否需要更细的拆分提交?这些优秀的工程实践,将会让代码库中的 commits 更加优雅。
commit 包含的信息?
commit 是如何表示的?
暂存区是什么?如何全部添加、一次添加、删除、查询和修正?
如何将暂存区的改动内容 commit?
不要做大提交,一个提交只做一件事。
工作区 (Working Directory)
暂存区 (Index)
Git 仓库 (Git Repo)
查看 commit 历史: git log (或 git log --oneline )。
在 commit 中查看改动的 diff:git log -p 。
查看 ref 与提交的关联关系,如当前 master 指向的 commit: git show master 。
检出覆盖: git checkout NAME (如果 NAME 是一个具体的提交哈希值时,Git 会认为状态是 “detached (分离的)”,因为 git checkout 过程中重要的一步是将 HEAD 指向那个分支的最后一次 commit。所以如果这样做,将意味着没有分支在引用此提交,所以若我们这时候进行提交的话,没有人会知道它们的存在)。
使用 git revert NAME 来对 commit 进行反转操作。
使用 git diff NAME 将旧版本与当前版本进行比较,查看 diff。
使用 git log NAME 查看指定区间的提交。
使用 git reset NAME 进行提交重置操作。
使用 git reset --hard NAME :将所有文件的状态强制重置为 NAME 的状态,使用上需要小心。
git branch b 命令可以让我们创建一个名称为 b 的分支。
当我们创建了一个 b 分支后,这也相当于意味着 b 的指向就是 HEAD 对应的commit。
我们可以先在 b 分支上创建一个新的 commit A ,然后假如切回 master 分支上,这时再提交了一个新的 commit B,那么 master 和 HEAD 将会指向了新的commit __B,而 b 分支指向的还是原来的 commit A。
git checkout b 可以切换到b分支上,切换后新的提交都会在b分支上,理所应当。
git checkout master 切换回 master 后,b 分支的提交也不会带回 master 上,分支隔离。
分支上提交隔离的设计,可以让我们非常轻松的切换我们的修改,非常方便的做各类测试。
commit 14: add feature x – maybe even witha commit message about x! commit 13: forgot to add file commit 12: fix bug commit 11: typo commit 10: typo2 commit 9: actually fix commit 8: actually actually fix commit 7: tests pass commit 6: fix example code commit 5: typo commit 4: x commit 3: x commit 2: x commit 1: x单就 Git 而言,这看上去是没有问题而且合法的,但对于那些对你修改感兴趣的人(很可能是未来的你!),这样的提交在信息在追溯历史时可能并没有多大帮助。但是如果你的提交已经长成这个样子,我们该怎么办? 没关系,Git 有办法可以弥补这一些: git commit --amend 我们可以将新的改动提交到当前最近的提交上,比如你发现少改了什么,但是又不想多出一个提交时会很有用。 如果我们认为我们的提交信息写的并不好,我要修改修改,这也是一种办法,但是并不是最好的办法。 这个操作会更改先前的提交,并为其提供新的 hash 值。 git rebase -i HEAD~13 这个命令非常强大,可以说是 Git 提交管理的神器,此命令含义是我们可以针对之前的 13 次的提交在 VI 环境中进行重新修改设计:
操作选项 p 意味着保持原样什么都不做,我们可以通过 vim 中编辑提交的顺序,使其在提交树上生效。
操作选项 r:我们可以修改提交信息,这种方式比 commit --amend 要好的多,因为不会新生成一个 commit。
操作选项 e:我们可以修改 commit,比如新增或者删除某些文件改动。
操作选项 s:我们可以将这个提交与其上一次的提交进行合并,并重新编辑提交信息。
操作选项 f:f代表着 "fixup"。例如我们如果想针对之前一个老的提交进行 fixup,又不想做一次新的提交破坏提交树的历史的逻辑含义,可以采用这种方式,这种处理方式非常优雅。
冲突只是因为 Git 不清楚你最终要合并后的文本是什么样子,这是很正常的情况。
产生冲突时,Git 会中断合并操作,并指导你解决好所有的冲突文件。
打开你的冲突文件,找到 <<<<<<< ,这是你需要开始处理冲突的地方,然后找到 ======= ,等号上面的内容是 HEAD 到共同祖先之间的改动,等号下面是 NAME 到共同祖先之间的改动。用 git mergetool 通常是比较好的选择,当然现在大多数 IDE 都集成了不错的冲突解决工具。
当你把冲突全部解决完毕,请用 git add . 来暂存这些改动吧。
最后进行 git commit ,如果你想放弃当前修改重新解决可以使用 git merge --abort ,非常方便。