git命令学习


git push -u origin master
已有仓库?

cd existing_git_repo
git remote add origin https://gitee.com/bai-wenzhong/git-study.git
git push -u origin master

一、初始配置


#工作区(未跟踪、已跟踪【未修改/已修改】)、暂存区(已暂存)、仓库-.git目录(已提交)

#配置用户、邮箱

$ git config --global user.name "张三"
$ git config --global user.email zs@qq.com

#查看配置

$ git config --list
$ git config user.name

#帮助命令格式

$ git help <verb>
#帮助命令举例:查看config命令用法
$ git help config

二、本地仓库基础操作


#建本地git仓库,方法1:

$ git init


#建本地git仓库,方法2:

$ git clone https://gitee.com/bai-wenzhong/git-study.git
$ git clone https://gitee.com/bai-wenzhong/git-study.git newname

#查看工作区、暂存区的文件状态

$ git status

#git add 命令用法

git add .
git add *.java
git add dir1 dir2 1.txt 2.txt

根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态

#.gitignore忽略文件
有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表
我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式
文件 .gitignore 的格式规范如下:
所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
可以使用标准的 glob 模式匹配。
匹配模式最后跟反斜杠(/)说明要忽略的是目录。
要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
举例1:

$ cat .gitignore
*.[oa] #忽略所有以 .o 或 .a 结尾的文件
*~忽略所有以波浪符结尾的文件

举例2:

# 此为注释 – 将被 Git 忽略
# 忽略所有 .a 结尾的文件
*.a
# 但 lib.a 除外
!lib.a
# 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目录下的所有文件
build/
# 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt

#比较工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容

$ git diff 

#比较已经暂存起来的文件和上次提交的快照之间的差异

$ git diff --cached 或 git diff --staged(Git 1.6.1以上版本支持)

#将暂存区文件提交到仓库

$ git commit -m "注释。。。"

#跳过使用暂存区,直接将工作区文件提交到仓库

$ git commit -a -m "注释。。。"

#移除文件
。。。。。。

#移动文件
。。。。。。

#查看提交历史

$ git log
。。。。。。

三、远程仓库基础操作

#查看当前仓库对应的远程仓库地址

git remote -v
#在克隆完某个项目后,至少可以看到一个名为 origin 的远程库,Git 默认使用这个名字来标识你所克隆的原始仓库

#添加远程仓库,一份本地代码可以对应多个远程仓库

git remote add [shortname] [url] #远程仓库的shortname尚不存在,才可以执行添加
$ git remote add pb git://github.com/paulboone/ticgit.git

现在可以用字符串 pb 指代对应的仓库地址了。比如说,要抓取所有 Paul 有的,但本地仓库没有的信息,可以运行 git fetch pb:

$ git fetch pb

#修改仓库对应的远程仓库地址

git remote set-url origin 仓库地址

#git fetch 将远端的数据拉到本地仓库,并不自动合并到当前工作分支
如果是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。所以,git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)

$ git fetch [remote-name]

#git pull
如果设置了某个分支用于跟踪某个远端仓库的分支(参见下节及第三章的内容),可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。
在日常工作中我们经常这么用,既快且好。
实际上,默认情况下 git clone 命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支。
所以一般我们运行 git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中的当前分支。

#推送数据到远程仓库

git push [remote-name] [branch-name]

如果要把本地的 master 分支推送到 origin 服务器上(再次说明下,克隆操作会自动使用默认的 master 和 origin 名字),可以运行下面的命令:

$ git push origin master

#查看远程仓库信息

git remote show [remote-name]
$ git remote show origin
	#origin url
    * remote origin
    URL: git@github.com:defunkt/github.git
    #已同步到本地的远端分支:issues、master
    Remote branch merged with 'git pull' while on branch issues
    issues
    Remote branch merged with 'git pull' while on branch master
    master
    #未同步到本地的分支:caching
    New remote branches (next fetch will store in remotes/origin)
    caching
    #已同步到本地、在远端服务器上已被删除的分支:
    Stale tracking branches (use 'git remote prune')
    libwalker
    walker2
    Tracked remote branches
    acl
    apiv2
    dashboard2
    issues
    master
    postgres
    #本地运行 git push 时缺省推送的远端分支:master
    Local branch pushed with 'git push'
    master:master

#修改某个远程仓库在本地的简称

$ git remote rename pb paul
$ git remote
    origin
    paul

#删除远程仓库

$ git remote rm paul
$ git remote
origin

四、本地分支-原理

#创建分支

$ git branch testing

 #切换分支

$ git checkout testing

#提交一次后的效果

#切回master分支

#再次提交

五、本地分支-新建、切换、合并

#新建前

#新建并切换分支解决53号bug

$ git checkout -b iss53

 等价与:

$ git branch iss53 #新建
$ git checkout iss53 #切换

 #53号bug修复了一半再切回master分支修复一个紧急问题

留心你的暂存区或者工作目录里,那些还没有提交的修改,它会和你即将检出的分支产生冲突从而阻止 Git 为你切换分支。切换分支的时候最好保持一个清洁的工作区域。稍后会介绍几个绕过这种问题的办法(分别叫做 stashing 和 commit amending)。目前已经提交了所有的修改,所以接下来可以正常转换到 master 分支

$ git checkout master

#创建一个紧急修补分支 hotfix ,进行修复

$ git checkout -b 'hotfix'
$ git commit -a -m 'xxx'

 #将hotfix 合并到master分支

请注意,合并时会出现“Fast forward”的提示。由于当前 master 分支所在的提交对象是要并入的 hotfix 分支的直接上游,Git 只需把 master 分支指针直接右移。换句话说,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)

$ git checkout master
$ git merge hotfix

#当前 hotfix 分支和 master 都指向相同的提交对象,所以 hotfix 已经完成了历史使命,可以删掉了:

$ git branch -d hotfix

#现在回到之前未完成的 #53 问题修复分支上继续工作:

$ git checkout iss53
$ git commit -a -m 'finished the new footer [issue 53]'

 不用担心之前 hotfix 分支的修改内容尚未包含到 iss53 中来。如果确实需要纳入此次修补,可以用 git merge master 把 master 分支合并到 iss53;或者等 iss53 完成之后,再将 iss53 分支中的更新并入 master

#在问题 #53 相关的工作完成之后,合并回 master 分支:

$ git checkout master
$ git merge iss53

这次,Git 会用两个分支的末端(C4 和 C5)以及它们的共同祖先(C2)进行一次简单的三方合并计算。对三方合并后的结果重新做一个新的快照,并自动创建一个指向它的提交对象(C6)。这个提交对象比较特殊,它有两个祖先(C4 和 C5)。

iss53 也就没用了,可以删除它

$ git branch -d iss53

六、本地分支-遇到冲突时的分支合并

没有发生冲突的文件,合并后会自动提交;

存在冲突的文件,会合并,但不会提交,它会停下来等你解决冲突。要看看哪些文件在合并时发生冲突,可以用 git status 查阅。

在解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决状态(译注:实际上就是来一次快照保存到暂存区域。)。因为一旦暂存,就表示冲突已经解决。

如果你想用一个有图形界面的工具来解决这些问题,不妨运行 git mergetool,它会调用一个可视化的合并工具并引导你解决所有冲突。退出合并工具以后,Git 会询问你合并是否成功。如果回答是,它会为你把相关文件暂存起来,以表明状态为已解决。

再运行一次 git status 来确认所有冲突都已解决。

如果觉得满意了,并且确认所有冲突都已解决,也就是进入了暂存区,就可以用 git commit 来完成这次合并提交。

七、本地分支-管理

git branch 命令不仅仅能创建和删除分支,如果不加任何参数,它会给出当前所有分支的清单:

$ git branch
    iss53
    * master
    testing

注意看 master 分支前的 * 字符:它表示当前所在的分支。也就是说,如果现在提交更新,master 分支将随着开发进度前移。若要查看各个分支最后一个提交对象的信息,运行 git branch -v

$ git branch -v
    iss53 93b412c fix javascript issue
    * master 7a98805 Merge branch 'iss53'
    testing 782fd34 add scott to the author list in the readmes

要从该清单中筛选出你已经(或尚未)与当前分支合并的分支,可以用 --merge 和 --no-merged 选项(Git 1.5.6 以上版本)。比如用 git branch --merge 查看哪些分支已被并入当前分支(译注:也就是说哪些分支是当前分支的直接上游。):

$ git branch --merged
    iss53
    * master

之前我们已经合并了 iss53,所以在这里会看到它。一般来说,列表中没有 * 的分支通常都可以用 git branch -d 来删掉。原因很简单,既然已经把它们所包含的工作整合到了其他分支,删掉也不会损失什么。

另外可以用 git branch --no-merged 查看尚未合并的工作:

$ git branch --no-merged
    testing

它会显示还未合并进来的分支。由于这些分支中还包含着尚未合并进来的工作成果,所以简单地用 git branch -d 删除该分支会提示错误,因为那样做会丢失数据:

$ git branch -d testing
    error: The branch 'testing' is not an ancestor of your current HEAD.
    If you are sure you want to delete it, run 'git branch -D testing'.

不过,如果你确实想要删除该分支上的改动,可以用大写的删除选项 -D 强制执行,就像上面提示信息中给出的那样。

八、远程分支-原理

1.假设你们团队有个地址为 git.ourcompany.com 的 Git 服务器。

如果你从这里克隆:

1)Git 会自动为你将此远程仓库命名为 origin,并下载其中所有的数据,建立一个指向它的 master 分支的指针,在本地命名为 origin/master(远程仓库名)/(分支名),但你无法在本地更改其数据。

2)Git 建立一个属于你自己的本地 master 分支,始于 origin 上 master 分支相同的位置,你可以就此开始工作

 2.如果你在本地 master 分支做了些改动,与此同时,其他人向 git.ourcompany.com 推送了他们的更新,那么服务器上的 master 分支就会向前推进,而于此同时,你在本地的提交历史正朝向不同方向发展。不过只要你不和服务器通讯,你的 origin/master 指针仍然保持原位不会移动

3.可以运行 git fetch origin 来同步远程服务器上的数据到本地。该命令首先找到 origin 是哪个服务器(本例为 git.ourcompany.com),从上面获取你尚未拥有的数据,更新你本地的数据库,然后把 origin/master 的指针移到它最新的位置上 

4.为了演示拥有多个远程分支(在不同的远程服务器上)的项目是如何工作的,我们假设你还有另一个仅供你的敏捷开发小组使用的内部服务器 git.team1.ourcompany.com。可以用 git remote add 命令把它加为当前项目的远程分支之一。我们把它命名为 teamone,以便代替完整的 Git URL 以方便使用 

5.现在你可以用 git fetch teamone 来获取小组服务器上你还没有的数据了。由于当前该服务器上的内容是你 origin 服务器上的子集,Git 不会下载任何数据,而只是简单地创建一个名为 teamone/master 的远程分支,指向 teamone 服务器上 master 分支所在的提交对象 31b8e 

九、推送本地分支到远程分支

1.如果你有个叫 serverfix 的分支需要和他人一起开发,可以运行 git push (远程仓库名) (分支名)

$ git push origin serverfix

若想把远程分支重命名,可以用 git push origin serverfix:newname 来推送数据。

2.接下来,当你的协作者再次从服务器上获取数据时,他们将得到一个新的远程分支 origin/serverfix,并指向服务器上 serverfix 所指向的版本

$ git fetch origin
    remote: Counting objects: 20, done.
    remote: Compressing objects: 100% (14/14), done.
    remote: Total 15 (delta 5), reused 0 (delta 0)
    Unpacking objects: 100% (15/15), done.
    From git@github.com:schacon/simplegit
    * [new branch] serverfix -> origin/serverfix

值得注意的是,在 fetch 操作下载好新的远程分支之后,你仍然无法在本地编辑该远程仓库中的分支。换句话说,在本例中,你不会有一个新的 serverfix 分支,有的只是一个你无法移动的 origin/serverfix 指针。

3.如果要把该远程分支的内容合并到当前分支,可以运行 :

$ git merge origin/serverfix

4.如果想要一份自己的 serverfix 来开发,可以在远程分支的基础上分化出一个新的分支来:

$ git checkout -b serverfix origin/serverfix

十、跟踪远程分支

从远程分支 checkout 出来的本地分支,称为 跟踪分支 (tracking branch)。跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。同样,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。

在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是 git push 和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如 origin 上除了 master 之外的其它分支。刚才我们已经看到了这样的一个例子:git checkout -b [分支名] [远程名]/[分支名]。如果你有 1.6.2 以上版本的 Git,还可以用 --track 选项简化:

$ git checkout --track origin/serverfix
    Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
    Switched to a new branch "serverfix"

要为本地分支设定不同于远程分支的名字,只需在第一个版本的命令里换个名字:

$ git checkout -b sf origin/serverfix
    Branch sf set up to track remote branch refs/remotes/origin/serverfix.
    Switched to a new branch "sf"

现在你的本地分支 sf 会自动将推送和抓取数据的位置定位到 origin/serverfix 了。

十一、删除远程分支

如果不再需要某个远程分支了,可以用这个非常无厘头的语法来删除它:git push [远程名] :[分支名]。如果想在服务器上删除 serverfix 分支,运行下面的命令:

$ git push origin :serverfix
    To git@github.com:schacon/simplegit.git
    - [deleted] serverfix

咚!服务器上的分支没了。你最好特别留心这一页,因为你一定会用到那个命令,而且你很可能会忘掉它的语法。有种方便记忆这条命令的方法:记住我们不久前见过的 git push [远程名] [本地分支]:[远程分支] 语法,如果省略 [本地分支],那就等于是在说“在这里提取空白然后把它变成[远程分支]”。

十二、分支的衍合-rebase

把一个分支中的修改整合到另一个分支的办法有两种:merge 和 rebase(衍合)

十三、基本的衍合操作

回顾分支合并,之前介绍过,最容易的整合分支的方法是 merge 命令,它会把两个分支最新的快照(C3 和 C4)以及二者最新的共同祖先(C2)进行三方合并,合并的结果是产生一个新的提交对象(C5)

 

其实,还有另外一个选择:你可以把在 C3 里产生的变化补丁在 C4 的基础上重新打一遍。在 Git 里,这种操作叫做衍合(rebase)。有了 rebase 命令,就可以把在一个分支里提交的改变移到另一个分支里重放一遍。

在上面这个例子中,运行:

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支 experiment)后续的历次提交对象(这里只有一个 C3),生成一系列文件补丁,然后以基底分支(也就是主干分支 master)最后一个提交对象(C4)为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象(C3'),从而改写 experiment 的提交历史,使它成为 master 分支的直接下游

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值