git自学基础

Git使用整理

1. Git 本地安装与配置

在git本地安装完成之后,你需要与公司的gitlab服务器做关联,这时候需要你有一个公司的gitlab账号,登陆并上传你的本地的ssh公钥。

 

2. 如何从公司的gitlab服务器上拉取一个项目到本地

第一步:克隆项目

git clone

image.png

 第二步:查看这个项目的远程服务端的分支情况

git branch -r

image.png

 第三步:信息分析

根据第二步的结果可以知道

a)     远程仓库一共有2个分支:master、v1.0.0

b)     远程分支指针指向的是master分支

第四步:拉取远程分支并创建本地分支

两中方式

a)    git fetch origin 远程分支名 : 本地分支名

b)    git checkout -b 本地分支名 origin/远程分支名

这里注意:

我们应该让本地分支名称与远程分支名称保持一致,方便后面提交。

image.png

此刻我们就在本地建立一个与远程仓库一模一样的仓库,并成的拉取了远程仓库的项目下来。

image.png

3. 如何在本地开发并提交我们的代码到远程仓库

由前面步骤可中得到,我们已经得到了项目源码了。此时我们还需要做一个工作:分支管理

我们需要在本地建立一个开发的分支。至于为什么?

看这篇文章:

http://blog.jobbole.com/109466/

http://nvie.com/posts/a-successful-git-branching-model

 image.png

然后我们在develop分支上修改代码,不会影响原来的v1.0.0分支。

 

4. 如何提交我们修改的代码

第一步:commit 我们的代码

image.png

第二步:合并 开发分支与v1.0.0分支

git merge --no-ff 要合并的分支名称

[注意]

      如果想把dev分支合并到v1.0.0上

      首先,切换到v1.0.0上,然后执行

      git merge --no-ff dev

第三步:同步远程仓库

提交之前先拉取远程仓库的分支与我们要提交的分支同步一下,如果其他人在你之前提交代码,那么远程库里的代码版本是比你的版本要高的,你再次提交会失败。

所有我们先同步一下远程的仓库

git pull命令的作用是,取回远程主机某个分支的更新,再与本地的指定分支合并。它的完整格式稍稍有点复杂。

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

比如取回origin主机的next分支,与本地的master分支合并,需要写成下面这样。

$ git pull origin next:master

 

如果远程分支是与当前分支合并,则冒号后面的部分可以省略。

$ git pull origin next

上面命令表示,取回origin/next分支,再与当前分支合并。

实质上,这等同于先做git fetch,再做git merge。

$ git fetch origin

$ git merge origin/next

 

在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动"追踪"origin/master分支。

Git也允许手动建立追踪关系。

git branch --set-upstream master origin/next

上面命令指定master分支追踪origin/next分支。

如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。

 

$ git pull origin

上面命令表示本地的当前分支自动与对应的origin主机"追踪分支"进行合并。

如果当前分支只有一个追踪分支,连远程主机名都可以省略。

 

$ git pull

上面命令表示,当前分支自动与唯一,一个追踪分支进行合并。

如果合并需要采用rebase模式,可以使用--rebase选项。

 

$ git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

如果远程主机删除了某个分支,默认情况下,git pull 不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull不知不觉删除了本地分支。

但是,你可以改变这个行为,加上参数 -p 就会在本地删除远程已经删除的分支。

$ git pull -p

# 等同于下面的命令

$ git fetch --prune origin

$ git fetch -p

 

第四步:提交

git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相仿。

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

注意,分支推送顺序的写法是<来源地>:<目的地>,因此

git pull  是<远程分支>:<本地分支>

git push 是<本地分支>:<远程分支>

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

 

$ git push origin master

上面命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。

如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。

 

$ git push origin :master

# 等同于

$ git push origin --delete master

上面命令表示删除origin主机的master分支。

 

如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。

$ git push origin

上面命令表示,将当前分支推送到origin主机的对应分支。

 

如果当前分支只有一个追踪分支,那么主机名都可以省略。

$ git push

 

如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push。

$ git push -u origin master

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

 

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

$ git config --global push.default matching

# 或者

$ git config --global push.default simple

还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用--all选项。

 

$ git push --all origin

上面命令表示,将所有本地分支都推送到origin主机。

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

$ git push --force origin

上面命令使用--force选项,结果导致远程主机上更新的版本被覆盖。除非你很确定要这样做,否则应该尽量避免使用--force选项。

最后,git push不会推送标签(tag),除非使用--tags选项。

$ git push origin -tags

 

5. 分支的合并模式

image.png

关于分支合并模式:

merge 分支的时候使用了参数 --no-ff,ff是 fast-forward 的意思,

--no-ff 就是禁用fast-forward。关于这两种模式的区别如下图。(可以使用 sourceTree 或者命令 git log --graph 查看。)

image.png

看了上面的图,那么使用非fast-forward模式来 merge 的好处就不言而喻了。我们知道哪些 commit 是某些 feature 相关的。虽然 git merge 的时候会自动判断是否使用fast-farward模式。但是有时候为了更明确,我们还是要加参数--no-ff 或者 --ff。

 

6. 分支的创建与管理

拉取远程分支并创建本地分支

方法一(推荐)

使用如下命令:

git checkout -b 本地分支x  origin/远程分支x

使用该方式会在本地新建分支x,并自动切换到该本地分支x。采用此种方法建立的本地分支会和远程分支自动建立映射关系。

 

方式二

使用如下命令:

git fetch origin 远程分支名x : 本地分支名x

使用该方式会在本地新建分支x,但是不会自动切换到该本地分支x,需要手checkout。采用此种方法建立的本地分支不会和远程分支建立映射关系。

 

1.在本地手动创建分支

git branch 要创建的分支名

2.本地分支切换

git checkout 要切换的分支名

3.从某个分支中拉取一个新的分支并切换到新分支

从 develop 分支建一个 feature 分支,并切换到 feature 分支

$ git checkout -b myfeature develop

 

4.删除本地分支

image.png

git branch -d dev-test

删除本地 dev-test 分支

 

7. git pull命令的使用

git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并,它的完整格式稍稍有点复杂。

使用语法

git pull [options] [<repository> [<refspec>…]]

描述:

将远程存储库中的更改合并到当前分支中。在默认模式下,git pullgit fetch后跟git merge FETCH_HEAD的缩写。更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。 使用--rebase,它运行git rebase而不是git merge

示例:

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

比如,要取回origin主机的next分支,与本地的master分支合并,需要写成下面这样

$ git pull origin next:master

如果远程分支(next)要与当前分支合并,则冒号后面的部分可以省略。上面命令可以简写为:

$ git pull origin next

上面命令表示,取回origin/next分支,再与当前分支合并。实质上,这等同于先做git fetch,再执行git merge 即:

$ git fetch origin

$ git merge origin/next

 

在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master分支。

git pull相当于是git fetch + git merge,如果此时运行git pull -r,也就是git pull –rebase,相当于git fetch + git rebase

https://blog.csdn.net/liuxiaoheng1992/article/details/79108233

1.Git手动建立追踪关系。

$ git branch  --set-upstream-to=dev origin/dev

上面命令指定本地dev分支追踪origin/dev分支。

 

如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。

$ git pull origin

上面命令表示,本地的当前分支自动与对应的origin主机”追踪分支”(remote-tracking branch)进行合并。

如果当前分支只有一个追踪分支,连远程主机名都可以省略。

$ git pull

上面命令表示,当前分支自动与唯一一个追踪分支进行合并。

 

如果合并需要采用rebase模式,可以使用–rebase选项。

$ git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

 

git fetch和git pull的区别

git fetch:相当于是从远程获取最新版本到本地,不会自动合并。

$ git fetch origin master

$ git log -p master origin/master

$ git merge origin/master

以上命令的含义:

首先从远程的 origin master主分支下载最新的版本到origin/master分支上,然后比较本地的master分支和origin/master分支的差别,最后进行合并

上述过程其实可以用以下更清晰的方式来进行:

 

//从远程的origin仓库的master分支下载到本地并新建一个分支temp

$ git fetch origin master : temp

$ git diff temp //比较master分支和temp分支的不同

$ git merge temp       //合并temp分支到当前所在的分支

2. git pull:相当于是从远程获取最新版本并merge到本地

git pull origin master

上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些,因为在merge前,我们可以查看更新情况,然后再决定是否合并。

2.关于 tag

image.png

 

8. 版本回退

1.撤销commit

reset方式:

1、找到之前提交的git commit的id

  git log  # 找到想要撤销的id

2、git reset --hard id

    回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被恢复的版本替换

归纳:

   git reset [<--soft> | <--mixed> | <--hard>] [<commint_id>]

   会对working tree和index和HEAD进行重置:
    gt reset –mixed 此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退 commit index 信息     git reset --soft 回退到某个版本,只回退了commit 的信息不会恢复到index file别,也就是说index file中依旧是更改后的文件,如果还要提交,直接commit即可
     git reset --hard 彻底回退到某个版本,本地(包括repository index workspace)的源码也会变为上一个版本的内容,此命令 慎用!

 

checkout方式:

git  checkout  --  <文件>丢弃工作区的改动

git checkout --readme.txt意思就是:把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

1.        readme.txt修改后还没有被放到index区域,现在撤销修改就回到和版本库一模一样的状态(上一次的git commit 后, 修改readme.txt 但没有执行git add, 回到上一次的git commit后的结果)

2.        readme.txt已经添加到暂存区后,又作了修改,现在撤销修改就回到添加到暂存区后的状态(修改readme.txt,并且git add[①],然后又修改了readme.txt, 此时执行git checkout,回到git add[①] 后的状态)

revert方式:

revert撤销一个提交的同时会创建一个新的提交。这是一个安全的方法,因为它不会重写提交历史。

      比如,下面的命令会找出倒数第二个提交,然后创建一个新的提交来撤销这些更改,然后把这个提交加入项目中。

git checkout hotfix

git revert HEAD~2    #回退到倒数第二个版本

image.png

 

9. 查看远程仓库地址信息

$ git remote -v

git@git.meiqia.com:fangzirui/auto-create-meta-schema.git (fetch)

git@git.meiqia.com:fangzirui/auto-create-meta-schema.git (push)

 

10. dev分支合并到线上

本地dev 分支新功能开发完成后,同步到远程线上分支上

1. 首先将本地的 dev 分支push到远程仓库

git push -u origin dev:dev

2. 切换到master分支

git checkout master

3. 将dev 合并到 master 并推送到远程master分支上

git merge –no-ff dev

git push -u origin master:master

4. 拉取并新建本地分支

git checkout -b origin/dev

 

11. gitignore 不起作用的解决办法

问题:

现在项目的根目录放了 .gitignore 文件,并且git远程仓库的项目根目录已经有了 logs文件夹。

由于每次本地运行项目,都会生成新的log文件,但是我并不想提交logs文件夹里面的内容,所以要在.gitignore写logs的规则。

我尝试过添加以下规则

logs/*.log

logs/

/logs/

 

但是运行git status的时候,始终能看到modified:logs/xx.log 。

请问是我的规则编写错误,还是我某个地方有理解错误?

git规则

.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的

解决办法:

git rm -r --cached .

git add .

git commit -m 'update .gitignore'

[参考文档]  https://segmentfault.com/q/1010000000430426

 

12. Git远程仓库地址变更本地如何修改

公司搬移, 作为git仓库的服务器IP地址变了。 本地代码挺多,重新检出太占时间,可以修改一个什么配置让我本地仓库和新的远程仓库建立关联吗, 答案是肯定的!

 

方法有很多,这里简单介绍几种:

以下均以项目git_test为例:

老地址:http://192.168.1.12:9797/john/git_test.git

新地址:http://192.168.100.235:9797/john/git_test.git

远程仓库名称: origin

 

方法一 通过命令直接修改远程地址

进入git_test根目录

git remote 查看所有远程仓库, git remote xxx 查看指定远程仓库地址

git remote set-url origin http://192.168.100.235:9797/john/git_test.git

 

方法二 通过命令先删除再添加远程仓库

进入git_test根目录

git remote 查看所有远程仓库, git remote xxx 查看指定远程仓库地址

git remote rm origin

git remote add origin http://192.168.100.235:9797/john/git_test.git

方法三 直接修改配置文件

进入git_test/.git

vim config

 

[core]

repositoryformatversion = 0

filemode = true

logallrefupdates = true

precomposeunicode = true

[remote "origin"]

url = http://192.168.100.235:9797/shimanqiang/assistant.git

fetch = +refs/heads/*:refs/remotes/origin/*

[branch "master"]

remote = origin

merge = refs/heads/master

修改 [remote "origin"]下面的url即可

 

方法四 通过第三方git客户端修改。

以SourceTree为例,点击 仓库 -> 仓库配置 -> 远程仓库 即可管理此项目中配置的所有远程仓库, 而且这个界面最下方还可以点击编辑配置文件,同样可以完成方法三。

 

13. 关于 pull request

对于什么是 pull request 请自行 Google

第一步:登录公司的gitlab,并fork至自己的workspace中

第二步:clone到本地的机器上

第三步:修改代码

第四步:push到自己的workspace

第五步:提交 pr (pr前一般会pull以下,然后在push)

假设我完成了某项功能,需要向线上版本进行提交,首先进行git fetch --all,拉取下来upstream,也就是线上版本的代码,并且将线上的代码合并到自己的分支上,解决冲突。

1. 涉及到的命令

添加远程仓库

git remote add <别名> <git地址>

 

建立追踪关系,并提交 pr 

git branch --set-upstream dev admin_house/dev
git pull adim_house dev:dev
git push admin_house dev:dev

 

或者在 gitlab上提交 pr

 

14. gitignore不起作用

现象描述:

.gitignore中已经标明忽略的文件目录下的文件,git push的时候还会出现在push的目录中

原因:

因为在git忽略目录中,新建的文件在git中会有缓存,如果某些文件已经被纳入了版本管理中,

就算是在.gitignore中已经声明了忽略路径也是不起作用的,这时候我们就应该先把本地缓存删除,然后再进行        git push,这样就不会出现忽略的文件了。

git清除本地缓存命令如下:

git rm -r --cached .
git add .
git commit -m 'update .gitignore'

 

posted @ 2017-03-28 13:41  lynchfang  阅读(153)  评论(0)    收藏  举报