zoukankan      html  css  js  c++  java
  • git常用命令收藏

     

    这个教程将介绍如何将一个新的项目导入到 git 之中,如何修改项目并如何将这些变更与其他开发者分享。

    如果你更感兴趣如何用 git 取出一个项目,比如,测试软件的最新版本,你可能更应该看看The Git User’s Manual的前两章。

    首先,记住你可以用 man 来获取 git 的文档,比如 "git diff" 的文档可以用如下命令察看:

    $ man git-diff

    在做任何改动之前,最好把自己的名字和 email 地址介绍给大家,最简单的方法就是:

    $ git config --global user.name "Your Name Comes Here"$ git config --global user.email you@yourdomain.example.com

    导入一个新项目

    假设你有一个名为 project.tar.gz 的 tarball 作为项目的初始内容。你可以如下操作来把它至于 git 版本控制之下。

    $ tar xzf project.tar.gz$ cd project$ git init

    Git 将会如下回复:

    Initialized empty Git repository in .git/

    现在,你已经初始化了工作目录——你可能已经注意到了名为 ".git" 的一个新目录了。

    下一步就是使用 git-add(1) 命令告诉 git 当前目录的所有文件 (注意这个点:.) 全是项目的一个快照:

    $ git add .

    这个快照目前存放在一个临时区域之中,在 git 中称为 "index"(索引)。使用 git-commit(1) 命令,你可以把 index 的所有内容永久性地存放到软件仓库之中:

    $ git commit

    这条命令会向你提示输入版本变更信息。这样,你的项目的第一个版本就已经存入 git 之中了。

    进行修改

    修改一些文件之后,你可以将更新这些内容到 index 之中:

    $ git add file1 file2 file3

    现在,你已经准备就绪,可以提交了。现在你可以使用 git-diff(1) 命令的 –cache 参数:

    $ git diff --cached

    (如果不使用 –cached 参数,git-diff(1)会显示所有还没添加进 index 的已经做出的改动。) 你也可以使用 git-status(1)来获得一些当前状况的概要信息:

    $ git status# On branch master# Changes to be committed:#   (use "git reset HEAD <file>..." to unstage)##       modified:   file1#       modified:   file2#       modified:   file3#

    如果你需要进行更多改动,现在就可以进行,然后可以添加到 index 之中。最后,使用如下命令提交改动:

    $ git commit

    这将再次要求你输入关于这次改动内容的描述性信息,之后记录下的项目新版本。

    此外,如果想省掉提交之前的git add命令,你可以直接用

    $ git commit -a

    这样会自动检测所有修改过的文件 (不包括新文件) ,并一气呵成地将它们添到 index 之中,并提交。

    关于提交的描述信息: 虽然这个信息不是必须的,但提交信息描述最好以一行不超过50个字符的概要性信息来开头,在一个空行之后再进行更多的描述。比如那些将 commit 转化为 email 的工具就会把这个第一行作为邮件标题,其余的提交内容则放在邮件内部。

    Git 跟踪内容而不是文件

    很多版本控制系统提供了一个 "add" 命令用来记录一个新文件。而 git 的 "add" 命令更加简单也更加强大: git add既用于新文件也用于新近改动的文件,在所有这些情况下,它在 index 中对所有的文件与状态进行一次快照,这样就可以在下一次 commit 命令中进行提交。

    Viewing project history

    在任何时候,你都可以如下查看所有你进行过的改动

    $ git log

    你可能还想看到每一步改进中的所有完整的 diff ,这可以使用如下命令

    $ git log -p

    浏览改动的概要对于获得每一步修改的情况常常是比较有用的,可以使用如下命令

    $ git log --stat --summary

    管理分支

    一个 git 仓库可以包含多个开发分支。使用如下命令可以建立一个称为 "experimental" 的新分支

    $ git branch experimental

    如果你运行命令

    $ git branch

    你将可以得到类似下面的已有分支的列表

      experimental* master

    "experimental" 就是你刚刚建立的那个分支,而 "master" 分支则是建立仓库的时候自动创建的缺省分支,里面的星号表示你当前所在的分支;输入命令

    $ git checkout experimental

    就可以切换到 experimental 分支。现在修改一个文件,并提交改变,然后重新回到 master 分支:

    (edit file)$ git commit -a$ git checkout master

    你会发现,刚才的变更已经不可见了,这是因为这个改变是发生于 experimental 分支的,而你现在已经回到 master 分支了。

    现在,你可以在 master 分支上做一些不同的变更:

    (edit file)$ git commit -a

    这里,两个分支已经产生不同了,每个分支上都发生了不同的改动。要把 experimental 中的改变也合并到 master 之中,运行命令

    $ git merge experimental

    如果两者的改变并不冲突,那么就算是完成了。而如果这里有冲突,有问题的文件左边会显示出标记,以表明这个文件发生了冲突;

    $ git diff

    上述命令将会列出具体的冲突。一旦你编辑文件解决了冲突,

    $ git commit -a

    这个命令将把合并的结果提交。最终,

    $ gitk

    会显示出漂亮的图标以展示历史变革。

    这里你可以使用如下命令删除 experimental 分支。

    $ git branch -d experimental

    这个命令会确定 experimental 中的所有改动已经在当前分支当中了。

    如果你在 crazy-idea 分支中进行开发,然后又后悔了,你可以用如下命令删除分支

    $ git branch -D crazy-idea

    分支操作十分简单而且代价低廉,所以适合于尝试一些东西。

    使用 git 进行协作

    假设 Alice 在 /home/alice/project 中的 git 仓库启动了一个新项目,而在本机中也拥有 home 目录的 Bob 想要贡献一些代码。

    他可以以如下工作开始:

    $ git clone /home/alice/project myrepo

    这会新建一个名为 "myrepo" 的目录,里面包含了 Alice 的仓库的一份克隆。这份克隆与原始项目完全一致,可以处理自己的一份原始项目历史。

    之后,Bob 进行了一些变更并提交了这些变动:

    (edit files)$ git commit -a(repeat as necessary)

    当他完成的时候,他告诉 Alice 将 /home/bob/myrepo 之中的变动导入到原始仓库之中。她使用如下命令来完成这一工作:

    $ cd /home/alice/project$ git pull /home/bob/myrepo master

    这会合并 Bob 的 "master" 分支到 Alice 的当前分支。如果 Alice 也已经修改了某些内容,她需要手工修复冲突。(注意,"master" 参数实际上并不是必要的,因为这是缺省分支。)

    "pull" 命令包括两个操作: 从远端分支中取出改动,然后合并到当前分支之中。

    当你只在一个很小的小组里工作的时候,通常不会频繁地访问同一个仓库。通过定义仓库的快捷方式,可以让访问远程仓库更方便一些:

    $ git remote add bob /home/bob/myrepo

    这样,Alice 可以如下用 "git fetch" 命令仅取出改动,而不把它们合并到当前分支之中:

    $ git fetch bob

    和长格式不同,当 Alice 使用 git remote设置的快捷方式从 Bob 的仓库中获取内容的时候,取出的内容存储在一个 remote tracking 分支之中,在本例中是 bob/master。所以,如下操作:

    $ git log -p master..bob/master

    将会列出从 Bob 从 Alice 的主分支中分支出去以后的所有改动。

    检查了这些变动之后,Alice 可以将这些变动合并到自己的 master 分支中:

    $ git merge bob/master

    这个合并也可以通过从自己的 remote tracking 分支中 pull 来做到,如:

    $ git pull . remotes/bob/master

    注意,git pull 总是合并进当前的分支,不论命令行给出的是什么。

    之后,Bob 可以如下使用 Alice 的最近改动更新自己的仓库

    $ git pull

    这里,他不需要给出 Alice 的仓库的位置;当 Bob 克隆了 Alice 的仓库的时候,git 在仓库设置中保存了她的仓库的位置,即 pull 所使用的位置:

    $ git config --get remote.origin.url/home/alice/project

    (git-clone 创建的完整配置信息可以用 "git config -l" 获得,git-config(1)的 man page 解释了所有选项的含义。)

    Git 也在 "origin/master" 分支保存了一份 Alice 的主分支的原始拷贝:

    $ git branch -r  origin/master

    如果其后 Bob 决定转到另一台主机上工作,他还可以通过 ssh 来克隆原始仓库:

    $ git clone alice.org:/home/alice/project myrepo

    此外,git 本身也有远程协议,并且可以使用 rsync 或 http,详细情况可以查看 git-pull(1)的 man page。

    Git 也可以使用类似 CVS 的工作方式,使用一个中心仓库,所有用户将改动推送到仓库之中,相关内容可以查阅 git-push(1)的手册页或git for CVS users

    浏览历史

    Git 的历史是通过一系列相互关联的 commit 构成的。我们已经通过 git log 命令看到了这些提交的列表。注意,每个 git log 条目的第一行是那次提交的名称:

    $ git logcommit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7Author: Junio C Hamano <junkio@cox.net>Date:   Tue May 16 17:18:22 2006 -0700
    
        merge-base: Clarify the comments on post processing.

    把这个名称用于 git show 命令,可以得到提交的详情。

    $ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7

    不过还有其他办法来指代这次提交。你可以只使用名称的开始部分,只要它足够长,保证在所有提交中是惟一的就行了:

    $ git show c82a22c39c   # the first few characters of the name are                        # usually enough$ git show HEAD         # the tip of the current branch$ git show experimental # the tip of the "experimental" branch

    每一次提交通常都有一次提交作为 "parent" ,它是项目的前一个状态:

    $ git show HEAD^  # to see the parent of HEAD$ git show HEAD^^ # to see the grandparent of HEAD$ git show HEAD~4 # to see the great-great grandparent of HEAD

    要注意,合并提交可能会有多个 "parent":

    $ git show HEAD^1 # show the first parent of HEAD (same as HEAD^)$ git show HEAD^2 # show the second parent of HEAD

    你还可以给你的提交一个名字; 命令

    $ git-tag v2.5 1b2e1d63ff

    让你可以使用 "v2.5" 来指代 1b2e1d63ff。如果你想把这个名字与他人共享 (比如标记一个发布版本),你应该建立一个 "tag" 对象,可能还需要签署它; 详情请查看 git-tag(1)的 man page。

    任何 git 命令都可以使用上述任何一种名字。比如:

    $ git diff v2.5 HEAD     # compare the current HEAD to v2.5$ git branch stable v2.5 # start a new branch named "stable" based                         # at v2.5$ git reset --hard HEAD^ # reset your current branch and working                         # directory to its state at HEAD^

    小心使用上述最后一个命令: 这将丢失工作目录中的所有改动,他还会清除本分支内随后的所有提交。如果这个分支是包含这些提交的惟一分支,它们将永远地丢失了。此外,不要对一个公众可见的、有其他开发者从中 pull 内容的分支使用 "git reset" 命令,这将导致一些不必要的合并来清除其他开发者的历史信息。如果你需要取消已经推送的改动,可以使用git-revert(1)命令。

    git grep 可以在项目的所有版本历史中寻找字符串,如下命令

    $ git grep "hello" v2.5

    会在版本 v2.5 中寻找所有 "hello" 的踪迹。

    如果你不提供 commit 名称,git grep 会在你当前的目录中搜索所有由 git 管理的文件。于是,如下命令

    $ git grep "hello"

    是搜索 git 跟踪的所有文件的便捷的方式。

    很多 git 命令可以处理一组提交,可以通过多种方式来指定版本。这里是一些 git log 的例子:

    $ git log v2.5..v2.6            # commits between v2.5 and v2.6$ git log v2.5..                # commits since v2.5$ git log --since="2 weeks ago" # commits from the last 2 weeks$ git log v2.5.. Makefile       # commits since v2.5 which modify                                # Makefile

    你给出的范围的上下边界不一定是严格的时间先后关系,比如,"stable-release" 分支可能会在 "master" 分支之后相当长一段时间才会引入同一个提交内容,这样

    $ git log stable..experimental

    将会列出 expermental 分支之中已经有的,而 stable 分支却还没有的提交,而命令

    $ git log experimental..stable

    将会列出 stable 中已有、但 experimental 却没有的提交。

    "git log" 命令有一个弱点:必须将所有提交在一个列表中呈现出来。当项目历史中有多个不同开发分支并最终合并到一起时,"git log" 中呈现出来的顺序可能没什么意义。

    大部分有大量开发者的项目 (比如 linux kernel 或 git 本身) 都经常合并分支,gitk 可以更好地将这些合并变化展示出来。比如,

    $ gitk --since="2 weeks ago" drivers/

    这个命令允许你浏览过去两个星期中在 "drivers" 目录之中的任意提交。(注意: 你可以按住 ctrl 键然后用 "-" 和 "+" 来调整 gitk 的字体大小。)

    最后,大部分命令可以带有文件名,这可以用于指定某次提交中的某个文件,从而指定某个文件的某个版本:

    $ git diff v2.5:Makefile HEAD:Makefile.in

    你还可以用 "git show" 命令去查看任意文件的任意版本:

    $ git show v2.5:Makefile
  • 相关阅读:
    perlcgiform2
    Linux的Find使用
    perl去除字符串前后的空格
    SQL快速查找
    026*:冷热启动优化、二进制重排、clang插桩(Header、Load Commands 、segment)(main函数前、main函数后)重签名 、ASLR、(PageFault 、System Trace、order文件)fsanitizecoverage=func,tracepcguard Dl_info
    阿里面试题:缓存的一些常见的坑,你遇到过哪些,怎么解决的?
    公司有着 30 多年经验的程序员被辞退了
    PHP7.3报错undefined function simplexml_load_string()(已解决)
    swoole框架中退出命令行程序仍然运行 php a.php &
    mysql服务器cpu爆满解决办法
  • 原文地址:https://www.cnblogs.com/cobbliu/p/2389003.html
Copyright © 2011-2022 走看看