您的位置:首页 > 其它

GIT学习笔记(持更)

2016-04-18 16:10 239 查看
取得git仓库

现存目录

cd此目录、git init

git init不会立马出现分支。只有add/commit一次之后,才会出现master分支

从远端已有库克隆

git clone [url] [new name]:最后一个参数可选。

git clone命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支

只能clone远程库的master分支,无法clone所有分支。

在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是 git push 和 git pull 一开始就能正常工作的原因。

解决办法如下:

git branch –a(列出所有分支,包括本地和远程)

git checkout -b [分支名] [远程名]/[分支名]

(从远程分支 checkout出来的本地分支,称为跟踪分支 (tracking branch)。跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。

命令背后的原理是clone远程的serverfix分支到本地,在本地起名为serverfix分支,并切换到本地的serverfix分支)

git checkout -b [分支名] [远程名]/[分支名] 与 git fetch的区别:

本地所缺少的分支,用git checkout -b [分支名] [远程名]/[分支名]下载下来,并建立链接关系。如以后远端已有变化,则用git fetch来更新。

分支相关操作

Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。Git 会使用 master 作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的 master 分支,它在每次提交的时候都会自动向前移动。

远程分支(remote branch)是对远程仓库中的分支的索引。它们是一些无法移动的本地分支;只有在 Git 进行网络交互时才会更新。远程分支就像是书签,提醒着你上次连接远程仓库时上面各分支的位置。

git branch

列出所有本地分支

git branch -r

列出所有远程分支

git branch -a

列出所有分支,远程分支用红色标出

git branch -v

查看各个分支最后一个提交对象的信息

git branch --merged

查看哪些分支已被并入当前分支

git branch --no-merged

查看尚未合并的分支

git branch –d [branch name]

删除分支

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

error:The branch 'testing'isnot an ancestor of your current HEAD.

If you are sure you want to delete it, run 'git branch -D testing'.


git branch –D [branch name]

强力删除该分支上的改动,可以用大写的删除选项
-D
强制执行

git fetch [远程主机名]

将某个远程主机的更新,全部取回本地。

默认情况下,git fetch取回所有已拥有的本地分支(branch)的更新。

git fetch [远程主机名] [分支名]

取回指定分支的更新

git push origin --delete <branchname>

删除远程分支

Git v1.7.0版本。

可以使用这种语法删除

git push origin :<branchname>

原理:推送一个空分支到远程分支,实际上就相当于删除远程分支。

git branch –d –r branchname

git branch -m | -M oldbranch newbranch

重命名分支,如果newbranch名字分支已经存在,则需要使用-M强制重命名,否则,使用-m进行重命名。

删除远程分支:git push --delete origin devel

重命名本地分支:git branch –m devel develop

再重新提交一个远程分支:git push origin develop

重命名远程分支,把devel分支重命名为develop分支。其实分三步。

比较内容差异

git diff

工作目录中当前文件和暂存区域快照之间的差异

(修改之后还没有暂存起来的变化内容)

git diff --cached/--staged

已暂存起来的文件和上次提交时的快照之间(版本库)的差异

git add

多功能命令

1.开始跟踪新文件

2.把已跟踪放入暂存区

3.合并时把有冲突的文件标记为已解决状态

功能3的场景:如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起。Git 作了合并,但没有提交,它会停下来等你解决冲突。在手动解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决状态。实际上就是来一次快照保存到暂存区域。因为一旦暂存,就表示冲突已经解决。如果觉得满意了,并且确认所有冲突都已解决,也就是进入了暂存区,就可以用 git commit 来完成这次合并提交。

git commit -a

把已跟踪的文件暂存起来一并提交,从而跳过git add(但并不会把未跟踪的文件提交)

与git add ./git commit的区别:忽略了未跟踪文件。

带上此参数对本地所有变更的文件执行提交操作。包括对本地修改的文件和删除的文件,但不包括未被版本库跟踪的文件。

优点:可以简化一些操作

缺点:丢掉了对提交内容进行控制的能力

撤销修改

场景1

当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时

git checkout -- file

会用暂存区的文件替换工作区的文件,回到最近一次git add的状态。

场景2

当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改

第一步用命令get reset HEAD file

第二步git checkout – file

其他git rm –cached <file>

第一步:暂存区的该文件会被master分支的该文件所替换,回到最近一次git commit的状态。工作区不变。

第二步:同上

其他:直接从暂存区删除文件,工作区不变。

场景3

已经提交了不合适的修改到版本库时,想要撤销本次提交

git reset --hard commit_id

版本回退

场景4

提交已推送到远程版本库

没办法了

远程仓库的使用

查看

git remote

查看当前配置有哪些远程仓库,列出远程仓库名

git remote –v(--verbose)

列出所有远程仓库名和对应的克隆地址

git remote show [remote-name]

查看某个远程仓库的详细信息

添加

git remote add [shortname] [url]

添加一个新的远程库,一个本地仓库可以对应多个远程仓库

删除

git remote rm [remote name]

删除指定的远程库

重命名

git remote rename [old remote name] [new remote name]

给指定远程库重命名

从远程库抓取数据

git clone

本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)

git fetch [remote-name]

此命令会到远程库中拉取所有你本地仓库中还没有的数据。会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。

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

git pull

自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。等于git fetch + git merge。建议少使用,因为经常会产生冲突。

推送数据到远程仓库

git push <远程主机名> <本地分支名>:<远程分支名>

如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。

要想和其他人分享某个本地分支,你需要把它推送到一个你拥有写权限的远程仓库。你创建的本地分支不会因为你的写入操作而被自动同步到你引入的远程服务器上,你需要明确地执行推送分支的操作。换句话说,对于无意分享的分支,你尽管保留为私人分支好了,而只推送那些协同工作要用到的特性分支。

只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,推送命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那你的推送操作就会被驳回。你必须先把他们的更新(git pull)抓取到本地,合并到自己的项目中,然后才可以再次推送。

如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用–force选项。

上面命令使用–force选项,结果导致在远程主机产生一个”非直进式”的合并(non-fast-forward merge)。除非你很确定要这样做,否则应该尽量避免使用–force选项。

git push origin master

把本地的 master 分支推送到 origin 服务器上master分支

git push -u origin master

将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。

本地master分支与origin分支作了链接

git push

不带任何参数的git push,默认只推送当前分支到绑定到远程仓库的远程分支(如没有绑定,则默认推送到origin主机的master分支),这叫做simple方式。此外,还有一种matching方式,会推送所有有对应的远程分支的本地分支。Git 2.0版本之前,默认采用matching方法,现在改为默认采用simple方式。如果要修改这个设置,可以采用git config命令。

$ git config --global push.default matching

# 或者

$ git config --global push.default simple

打标签

同大多数 VCS 一样,Git 也可以对某一时间点上的版本打上标签。人们在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做。

列出现有标签

git tag

显示的标签按字母顺序排列,所以标签的先后并不表示重要程度的轻重。

创建一个含附注类型的标签

git tag –a [标签名] –m[附注]

a是annotated的首字母。git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;

创建一个轻量级标签

git tag [标签名]

轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用

查看相应标签的版本信息

git show [标签名]

如果是附注类型标签,会显示提交对象。

如果是轻量级标签,则只有相应的提交对象摘要。

后期加注标签

git log

git tag –a [标签名] [校验和]

查到那次你想加注标签的commit的校验和

给该commit打上标签

分享标签

git push 并不会把标签传送到远端服务器上

只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,

运行

如果要一次推送所有本地新增的标签上去,可以使用 --tags 选项

现在,其他人克隆共享仓库或拉取数据同步后,也会看到这些标签。

git push [remote name] [tagname]:推送指定标签

git push [remote name] --tags:一次推送所有本地新增的标签上去

删除tag

git push origin --delete tag <tagname>


git cherry-pick

cherry-pick就是从不同的分支中捡出一个单独的commit,并把它和你当前的分支合并。如果你以并行方式在处理两个或以上分支,你可能会发现一个在全部分支中都有的bug。如果你在一个分支中解决了它,你可以使用cherry-pick命令把它commit到其它分支上去,而不会弄乱其他的文件或commit。

1

在commit所在分支找到需要pick的commit

git log --pretty=oneline -–grep “keywords”

搜索commit关键词,复制前几位的hash值

2

切换到想要合并的分支上

git checkout “branch-name”

3

把该commit pick到此分支

git cherry-pick “commit-id”

4

把此分支push到远端对应的分支

git push origin “本地分支名”:“远程分支名”

Gitlab代码提交流程

需要他人审核代码:

1.从本地master分支开始,建立本地fixbug分支

2.修改代码

3.切回本地master分支,更新到最新

4.把本地fixbug分支rebase到最新的本地master

5.把本地fixbug分支push到远端的同名分支

6.gitlab页面上申请merge request

7.他人接受merge request之后就可以删除本地fixbug

无需他人审核

1.直接在本地master上改动,然后直接推送到远程master

冲突场景及解决

1

本地分支相互切换时,留心你的暂存区或者工作目录里,那些还没有提交的修改,它会和你即将检出的分支产生冲突从而阻止 Git 为你切换分支。

1.把修改提交

2.绕过这种问题的办法(分别叫做 stashing 和 commit amending)

2

有时候merge操作并不会如此顺利。如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起(这种问题只能由人来裁决。)

Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突。

解决后要记得删除了 <<<<<<<,======= 和 >>>>>>> 这些行。

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

3

删除还未merge进来的分支时,由于这些分支中还包含着尚未合并进来的工作成果,简单的用git branch –d删除该分支会提示错误

git branch –D强制执行

常见概念总结

Fast forward

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

non-fast-forward

场景:

当要push代码到git时,出现提示:

error:failed to push some refs to ...

Dealing with “non-fast-forward” errors

From time to time you may encounter this error while pushing:

$ git push origin master

To ../remote/

! [rejected] master -> master (non-fast forward)

error: failed to push some refs to '../remote/'

问题(Non-fast-forward)的出现原因在于:在你修改本地分支代码的这段时间,远程分支已经有所更新。所以它不允许你直接把你的代码覆盖上去。于是你有3个选择方式:

1,强推,即利用强覆盖方式用你本地的代码替代git仓库内的内容

git
push –f(--force)

2,先把git的东西fetch到你本地然后merge后再push

$
git fetch

$
git merge

这2句命令等价于git pull

3,git
pull --rebase origin [分支名]

其他/技巧

简写配置

git
config –global alias.[缩写] [全称]

邮箱配置

其他

M表示从原来分支(上一次修改没有提交)带过来的修改

可能会显示一些不存的远程分支,最终以gitlab为准。

non-fast-forward说明你的分支太老了。

解决:git pull --rebase origin v2.2.x。

再推送

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: