Git在现在应该是使用得最多的版本管理工具了,本片博客将持续更新它的使用方法,以及在平时开发中遇到的问题及解决方法,至于它与SVN或者其它的工具有什么区别这里就不谈了,不是重点
在Git中,我们将需要控制的文件目录叫做一个仓库,每个项目的所在文件夹可以简单理解成一个仓库。假如现在建立一个仓库,那这个文件夹中就有以下文件
WorkSpace文件夹:需要通过git进行版本控制的项目文件,通常是你的项目文件夹,除了.git文件夹之外的都属于工作区
.git 文件夹:创建仓库的时候自动创建,所有的版本信息,操作记录全在这个文件夹里面,尽量不要修改或者删除里面的文件
一个仓库分区图如下:
其中的
Index/Stage:暂存区或者待提交更新区,在提交进入仓库前,所有add命令操作的更新放在暂存区
Local Repository:存放在本地的仓库,指当前的开发分支
Stash:工作状态保存栈,用于保存或者恢复工作区的临时状态,后续会有样例进行使用
在.git目录下有以下文件
在开发工具中,在版本管理工具支持下,被纳入版本管理的文件通常有一些不同的颜色
在公司里我们做的最多的就是拿到远程仓库地址,然后使用命令将远程仓库拉到本地
先进入你要存放仓库的目录,然后右键,选中git bash,这是一个git的命令行工具,输入以下命令:
git clone https://github.com/xxxxx/xxxxxx.git 或者
git clone ssh://github.com/xxxxx/xxxxxx.git
git支持多种协议,但通过ssh支持的原生git协议速度最快
这样拉取仓库会把所有的历史提交记录全拉下来,导致本地.git目录非常大,这时候如果不考虑回滚的情况可以在后面追加–depth命令,如下
git clone https://github.com/xxxxx/xxxxxx.git --depth=1
这样就只会clone最后一次commit记录
代码拉下来后,我们一般不在master分支提交代码,需要切换到自己的开发分支进行操作,可以通过以下命令进行操作
列举分支
比如所有分支情况如下:
~/mxnet$ git branch -a
* master
devp
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/devp
可以看到 * master 表示我们本地当前分支,remotes/origin/master和remotes/origin/devp是远程仓库的两个分支,第三行意思是指向当前远程分支
切换分支
这时候我们需要切换到devp分支,使用如下命令
$ git checkout devp
新建分支
如果需要新建分支,使用如下命令
$ git branch new_branch
新建并切换分支
在上面的例子中,分别使用两个命令创建和切换分支。 Git为checkout命令提供-b选项; 此操作将创建一个新的分支,并立即切换到新分支。
$ git checkout -b devp
接下来还可以将这个新建的分支推送到远程,如下:
$ git push --set-upstream origin devp
删除分支
可以通过向git branch命令提供-D选项来删除分支。,但在删除现有分支之前,请切换到其他分支
$ git branch -d new_branch
删除远程分支
git push origin --delete
重命名分支
假设需要在项目中添加对宽字符的支持。并且已经创建了一个新的分支,但分支名称需要重新命名。那么可通过使用-m选项后跟旧的分支名称和新的分支名称来重新命名分支名称
$ git branch -m new_branch wchar_support
想查看git的提交信息可以通过该命令及扩展形式
git log
该命令按提交时间列出所有的更新,最近的更新排在最上面
在命令行界面会列出每个提交的 SHA-1 校验、作者的名字和电子邮件地址、提交时间以及提交说明
git log -n
上面的命令会列出所有的更新信息,但是有时候你只要看最近的几条,
那就在后面接 -n 表示查看最近n此的提交概要信息,这个n可以是1,2,3......
git log --oneline
这个命令如同名字一样,每个提交展示的信息只有一行,可以让你快速浏览提交信息
git log --pretty=oneline
这个命令展示commitid信息是全的,其它的跟git log --oneline一样
git log --stat
该命令包含上面的命令的信息,除此之外还能展示每次提交的一些简略的统计信息,比如哪些文件被修改了,
多少文件有变化,增加了多少行,删除了多少行
git log --name-only
该命令会显示已修改的文件清单,没有 --stat命令的统计信息
git log -p -n
上面展示的只是概要信息,你如果想看具体提交的内容,可以加上-p参数
该选项除了显示基本信息之外,还附带了每次 commit 的变化,比如某个文件哪一行代码被修改了,
就会在那一行列出修改前的内容和修改后的内容,修改前的用红色-开头,修改后的用绿色+开头
当进行代码审查,或者快速浏览某个搭档提交的 commit 所带来的变化的时候,这个参数就非常有用了
git show commitid
通过上面的命令你可以获取到每次提交的校验码,比如:
commit dc6b155e824ec6300e292f16c434620ac9ce10e7
然后就可以通过show命令查看某次提交的具体内容
你并不需要将校验码全部输入,只用将开头的几个字母输入就行了,git会以这个输入内容作为开头进行匹配,比如
git show dc6b
git log --author
查看指定作者的简要提交信息,author后接提交者名字;可以使用git log --stat --author xxx 查看具体提交文件信息,
其它命令也可以组合使用
git log --since
查看指定时间之后的提交信息,since后接时间,比如2019.02.20,包含指定时间
git log --until
查看指定时间之前的提交信息,until后接时间,比如2019.02.20,包含指定时间
git blame file
查看指定文件里的内容,用具体文件名或者文件路径替代file
git log – file
查看指定文件的提交历史
git log -p – file
查看指定文件的每次提交的具体修改信息
git show commitid – file
查看某次提交中指定文件的修改信息
这个也是查看日志,但是可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作),例如执行 git reset --hard HEAD~1,退回到上一个版本,用git log则是看不出来被删除的commitid,用git reflog则可以看到被删除的commitid,我们就可以买后悔药,恢复到被删除的那个版本
git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并,它的完整格式如下:
$ git pull [options] [ […]]
$ git pull <远程主机名> <远程分支名>:<本地分支名>
比如,要取回origin主机的next分支,与本地的master分支合并,需要写成下面这样
$ git pull origin next:master
如果远程分支(next)要与当前分支合并,则冒号后面的部分可以省略
$ git pull origin next
上面命令表示将远程origin主机的next分支拉取过来和本地的当前分支进行合并。实质上,这等同于先做git fetch,再执行git merge
$ git fetch origin next:master
$ git merge master
在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master分支
如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名
$ git pull origin
上面命令表示,本地的当前分支自动与对应的origin主机”追踪分支”(remote-tracking branch)进行合并
如果当前分支只有一个追踪分支,连远程主机名都可以省略
$ git pull
上面命令表示,当前分支自动与唯一一个追踪分支进行合并
git fetch和git pull的区别
git fetch:相当于是从远程获取最新版本到本地,不会自动合并
$ git fetch origin master
$ git log -p master..origin/master
$ git merge origin/master
以上命令的含义:
上述过程其实可以用以下更清晰的方式来进行:
$ git fetch origin master:tmp //从远程的origin仓库的master分支下载到本地并新建一个分支temp
$ git diff tmp //比较master分支和temp分支的不同
$ git merge tmp//合并temp分支到master分支
$ git branch -d temp//删除temp分支
git pull:相当于是从远程获取最新版本并merge到本地
git pull origin master
上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些,因为在merge前,我们可以查看更新情况,然后再决定是否合并
当我们正常进行项目开发后需要将修改的文件和新增的文件推送到远程仓库,首先进行add命令,将内容添加到暂存区
add命令有如下几种:
git add msg.txt:将msg.txt文件添加到暂存区
git add document/:将document整个目录提交到暂存区
git add document/*.txt:将document目录下以.txt结尾的文件提交到暂存区
git add . :这个 . 表示当前目录所有文件及文件夹,会监控工作区的状态树,包括所有内容修改的文件和新文件,但不包括被删除的文件,然后提交到暂存区
git add -u . :仅监控已经被add过的文件(即tracked file),会将被修改的文件和删除的文件提交到暂存区,
git add -A . :第4个命令和第5个命令的合集,表示将所有已跟踪的文件的修改和删除,未被跟踪的新增文件都提交到暂存区
git add -i . :查看所有文件的状态信息,不包括新增且没被提交到暂存区的文件
git add -f filename :强制提交文件
当我们习惯性的通过git add . 命令将所有文件添加到了暂存区,但是其实我们想其中一个文件不要被提交到暂存区,这就需要撤销这个文件的add操作,这时使用 git reset HEAD 文件名 进行撤销。该文件就回到了add之前的状态。
当我们对已被追踪的文件进行错误的修改后,希望取消这些修改(这些修改没有被add),回到修改前的状态,使用git checkout – 文件名
当将修改的文件,新增的文件,删除的文件进行add操作添加到暂存区后,需要提交到本地仓库,提交命令如下
git commit -m “此次提交描述”
-m 表示在后面追加此次提交的备注信息,
当我们要输入的这个备注信息很长,可以使用如下命令
git commit -m '
message1
message2 '
这样提交操作就完成了;
如果不加这个 -m 参数,只有git commit ,那么敲回车键后会调用一个编辑器,默认是vim来让你输入这个 备注信息;
输入后怎么退出这个编辑器回到命令行呢,按下 esc ,这样就会退出编辑状态,然后连续按两次大写字母 Z ,这样就会
正常回到命令行界面。
git commit -a -m “此次提交描述”
加-a参数可以将所有已跟踪文件中的执行修改或删除操作的文件都提交到本地仓库,即使它们没有经过git add添加到暂
存区,注意,新加的文件(即没有被git系统管理的文件)是不能被提交到本地仓库的。建议一般不要使用-a参数,正
常的提交还是使用git add先将要改动的文件添加到暂存区,再用git commit 提交到本地版本库。
当代码提交到本地仓库后要做的就是推送到远程仓库,推送命令如下
git push 的一般形式为 git push <远程主机名> <本地分支名> : <远程分支名>
git push origin master: master
意思是将本地master分支推送到远程主机origin上的master分支,
origin是主机名,第一个master是本地分支名,第二个是远程分支名。
可以使用git branch 查看本地分支,git branch -r查看远程分支
git push origin master
如果远程分支名忽略,表示将本地分支推送到与之存在追踪关系的远程分支(通常两者同名),如果远程分支不存在,
则会被新建一个远程分支,可以通过git branch -vv 命令 查看本地分支与远程分支的追踪关系
git push origin : master
如果本地分支名省略,表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支,
等同于git push origin --delete master (master是远程分支名)
git push origin
如果本地分支和远程分支都省略,表示将当前分支推送到origin主机对应的分支,前提是当前分支和远程分支存在追踪关系
git push
如果当前分支只有一个远程分支,那么主机名都可以省略
git push -u origin master
如果当前分支与多个主机存在追踪关系,则可以使用 -u 指定一个远程主机,
意思就是将本地master分支推送到origin主机,同时指定origin为默认主机,这样之后就可以不加参数直接使用git push
git push --all origin
表示将所有本地分支推送到远程主机上
如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机
git push --force origin
强制将本地所有分支推送到远程主机,可能会导致在远程主机产生一个”非直进式”的合并,不建议这么做
git push origin master : refs/for/master
表示推送到远程master分支的代码需要经过code review之后才能进行merge的,而使用refs/heads/ 就不会检查,
直接推送到远程分支
该命令是用来对工作区的文件做备份的,git中由于可能存在多个Stash的内容,所以用栈来管理,stash只会保存在本地
git stash
这个命令做的就是将工作区的代码恢复到上次提交的内容,并且将你本地所做的修改进行备份;
如果要添加备份信息,可以使用git stash save "本次备份原因"
git stash list
显示Git中stash栈内的所有备份,可以利用这个列表来决定从哪个stash恢复
git stash drop
删除指定stash,后面接stash名字,比如git stash drop stash@{0}
git stash clear
清空Git中stash栈,删除所有stash。此时使用gitg等图形化工具会发现,原来stash的那些节点都消失了
git stash pop
这个命令就是从最近的一个stash中读取内容并应用到当前的工作目录下,同时删除该stash备份
git stash apply
git stash pop命令使用完stash后会删除该stash,而这个命令也是使用stash但不会删除stash,
后面还可以跟stash名字,比如git stash apply stash@{0},默认使用第一个stash
git stash show
查看stash中具体备份的文件信息,后面可接stash名字,默认查看第一个;后面接-p参数可以查看文件内容信息
git stash -u
git stash默认只会备份添加到暂存区的修改(staged changes)和 Git跟踪的但并未添加到暂存区的
修改(unstaged changes),而新增加的文件(untracked files)不会备份,而该命令可以stash untracked files
git stash -a
上面一条命令不会备份被忽略的文件(ignored files),使用该命令是备份所有文件
使用git remote -v查看远程仓库地址
使用git remote show origin查看仓库信息
建立本地分支与远程分支的追踪关系命令格式如下:
git branch --set-upstream-to origin/
比如下面,将本地dev分支和远程dev分支建立追踪关系
git branch --set-upstream-to origin/dev dev
如果是将当前分支与远程分支建立追踪关系,可以这样写
git branch --set-upstream-to origin/dev
最后可以使用如下命令查看所有分支关联关系
git branch -vv
建立关联关系还可以使用这个命令:git branch -u origin/dev dev
比如你突然接到一个紧急电话,产品出了一个大bug,需要立即修复,这时候就可以这样:
从正在开发新需求的分支devnew切换到已经发布到生产服务器上的分支master
git checkout master
为这次紧急修复新建一个分支devbug,并进入这个分支,然后在这个分支上修复问题
git checkout -b devbug // 在生产服务器上新建一个devbug分支并进入该分支,在这个分支上进行bug修复
测试通过后回到生产服务器上的分支master,将新分支devbug合并过来,然后再推送到生产服务器上
git checkout master //回到生产服务器上的分支
git pull origin master //如果master分支有更新,需要先把代码拉下来
git merge --no-ff devbug -m "合并描述信息" //将修复分支合并到master分支
git push origin master //将修复代码推送到远程master分支,如果有冲突,需要先解决冲突
git branch -d devbug //删除修复bug的分支,当然你也可以不删除
切换到之前开发新需求的分支继续工作
git checkout devnew
这里要注意下git merge命令后面有几种选项:
如果merge命令后面不加,默认是–ff
差异如图
merge的不同行为,向后看,其实最终都会将代码合并到master分支,而区别仅仅只是分支上的简洁清晰的问题;然后向前看,也就是我们使用reset 的时候,就会发现,不同的行为就带来了不同的影响
通常我们把 master 作为主分支,上面存放的都是比较稳定的代码,提交频率也很低,而 develop 是用来开发特性的,上面会存在许多零碎的提交,快进式合并会把 develop 的提交历史混入到 master 中,搅乱 master 的提交历史。所以如果你根本不在意提交历史,也不爱管 master 干不干净,那么 –no-ff 其实没什么用。不过,如果某一次 master 出现了问题,你需要回退到上个版本的时候,你就会发现退一个版本居然退到了分支的某次版本,而不是想要的master分支的上一个版本,因为 feature 的历史合并进了 master 里。这也就是很多人都会推荐 –no-ff 的原因了吧。
合并提交
上面说的是合并分支,但是有时候你的代码需要提交到多个分支上去,那怎么办呢?总不能每个分支都拷贝下代码然后提交吧,这时候就需要使用cherry-pick命令了
首先假如你在dev-11分支上,做了add、commit、push操作到远程dev-11分支了,然后你又想把这次提交的代码再提交到dev-22分支上,那么先使用git log命令查看你这次提交的commitid,这个很重要
接下来使用git checkout命令切换到dev-22分支上,再使用git cherry-pick命令将这个commit提交到dev-22分支上,比如
git cherry-pick 27ff9daccd0d6ca6419ba4d0849436ef47f92f6b
最后再使用git push origin dev-22命令推送到远程分支上
git diff branch1 branch2
显示出所有有差异的文件的详细差异,它是在git bash命令框内展示
git diff branch1 branch2 --stat
仅显示出所有有差异的文件列表
git diff branch1 branch2 >>diff.diff
在当前目录生成一个diff.diff文件,导出所有差异内容
修改本地分支名很简单,比如我要将本地分支dev-11修改为dev-22:
git branch -m dev-11 dev-22
如果要修改远程分支名的话,有个前提是先把远程分支拉到本地,接下来的操作其实就是先删除远程分支,然后修改本地分支名,接着推送到远程仓库,最后就是切换到这个远程分支,并将本地分支与远程分支建立追踪关系
git branch -m dev-11 dev-22//重命名本地分支
git push --delete origin dev-11//删除远程分支
git push --set-upstream origin dev-22 //把修改后的本地分支推送到远程
假如在操作过程中误删了文件或文件夹,也有可能是你就想删除这个文件夹;删除了以后怎么恢复呢?
这时候需要使用git checkout 命令
第一步
通过git status命令查看文件状态
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
deleted: sql/isp.sql
modified: src/main/resources/application.properties
no changes added to commit (use "git add" and/or "git commit -a")
可以看到这里我将isp.sql这个文件删掉了
第二步
使用git checkout sql/isp.sql,这个命令的意思就是放弃对工作目录中的更改
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git checkout -- sql/isp.sql
这样这个被你删除的文件就又恢复了,这里我试过不输入 – 直接使用git checkout sql/isp.sql也是可以的
其实不光被删除的文件,包括对已被追踪的文件进行的修改都可以使用这个命令恢复到修改前的状态,前提是没有对这些修改使用add命令
有时候你会碰到这种情况,我修改了某些文件,并将其通过add命令添加到暂存区了,但是此刻我发现提错了,需要撤回,这时候就可以使用git reset命令了,如下:
查看状态
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: sql/isp.sql
no changes added to commit (use "git add" and/or "git commit -a")
可以看到isp.sql文件被修改了
接下里通过 git add sql/isp.sql 命令添加到暂存区,再次查看状态
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: sql/isp.sql
可以看到这个文件正在等待commit
这时候发现文件有错误,想要撤回刚才的add操作,就可以通过reset命令,如下
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git reset HEAD sql/isp.sql
Unstaged changes after reset:
M sql/isp.sq
这时候再查看状态
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: sql/isp.sql
no changes added to commit (use "git add" and/or "git commit -a")
这样就回到了add操作前的状态了
注意:这时候你要想把文件内容也恢复到修改前的内容,可以通过checkout命令将本地仓库的内容覆盖掉该文件
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git checkout sql/isp.sql
这时候再查看状态
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
该文件就跟仓库里的一模一样了,抹除了你的修改
当我们进行了一次错误的提交commit,但是还未进行push操作,那么如何将这个commit撤销呢?
方法很简单,使用git log或者git reflog命令查看提交记录,找到你要找的那次提交的commit id,然后就是回退版本:
git reset --hard Obf3564
Obf3564就是commit id
版本回退分两种情况:
第一种就是远程分支只有自己使用,这种情况下因为没有同事的提交记录,只有自己的commit,进行版本回退比较简单;通常情况下就是我们push了一次错误的代码或者无用的代码到远程分支,那么就需要回滚到之前的某个版本,操作如下:
本来本地分支和对应的远程分支版本下的README.md文件内容如下
然后在本地修改该文件内容
接下来将其推送到远程分支,然后看看log
但是我们发现最近的提交【readme】没有用,需要回退到最近一个正常的版本,怎么做呢?如下
$ git reset --hard 2055dc2c963848
这就是先将本地分支回退到上一个版本,看看该文件内容
可以看到文件内容已经恢复了,但是远程分支还没有变化,所以需要进行如下操作:
$ git push -f
这句命令意思是将本地分支内容强制推送到远程分支,也就是覆盖远程分支的意思,这个命令在多人开发时慎用,除非这个分支只有你一个人用;这样操作后,版本就回滚了
第二种情况就是远程分支是多人使用的,这时候就稍微麻烦点了,就不能再像上面那样回退版本了,因为公共分支包含同事提交的代码,你一回退,很可能就直接把别人的提交给弄丢了
版本回退
reset、revert
有时候使用git pull命令会出现以下提示
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0.local (master)
$ git pull
error: Your local changes to the following files would be overwritten by merge:
sql/isp.sql
src/main/resources/mybatis/mybatis-config.xml
Please commit your changes or stash them before you merge.
Aborting
Updating 086076a..e2b5535
出现这个的原因就是同一个文件同事修改过并且将修改提交到了远程仓库,这时候你也对这个文件的同一处进行了修改,那么直接拉取代码会覆盖掉本地你做的修改,所以你要做的就是要么先commit你的修改,要么使用stash命令先备份
一般情况下不直接使用commit,因为会导致冲突,且会将冲突提交到远程仓库
所以就是用stash命令,使用方法如下:
第一步:备份
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0.local (master)
$ git stash save "本次备份原因"
这个命令做的就是将工作区的代码恢复到上次提交的内容,并且将你本地所做的修改进行备份(包括add到暂存区的和未add到暂存区的),如果不加stash信息,可以直接使用git stash
第二步:恢复且备份后就可以拉取代码了
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0.local (master)
$ git pull
第三步:恢复备份
lenovo@DESKTOP-L1PKA9E MINGW64 /d/Web/ISP/ISPServerv1.0.local (master)
$ git stash pop
这个命令就是从最近的一个stash中读取内容并恢复工作区的相关内容,同时删除该stash备份;也就是将第一步备份的代码合并到当前工作区代码,有可能会产生冲突,需要手动在文件中进行修改
git push origin master : master
当我使用这个命令进行提交的时候,报错如下
error: dst ref refs/heads/master receives from more than one src.
error: failed to push some refs to 'http://xx.xx.xx.xx/xx/xxv3.00.xx.git'
出现这种情况是因为我们的命令里出现了两个空格,即冒号与分支名之间存在空格
其实对于用户来说,是由于空格导致的问题,毕竟在shell中由于空格出现的问题不少
但是对于git来说,多一个空格就多了一个参数,
本来只需要【push】 【origin】 【master:master】 三个参数
但是我却给了5个参数【push】 【origin】 【master】 【:】 【master】
使用git pull的时候报了这个错,这是因为在之前某次pull代码自动合并出现错误,在【git fetch和git pull的区别】这一节可以知道,git pull相当于是先fetch再merge;所以这里再次pull操作之前需要将上次的合并完成,做法如下:
$:git merge --abort
$:git reset --merge
$:git pull
这里是保留本地的更改并中止合并;然后重新合并;最后拉取代码
接下来就可以将你的代码提交了
其实还有一种更残暴的做法,比如你出现这种错误后,可以不保留自己本地的修改,直接将远程仓库代码合并到本地,那就使用如下方法
$:git fetch --all
$:git reset --hard origin/master
$:git fetch
git reset --hard ORIG_HEAD这个命令会清空你的working tree,即丢弃你的本地未add的那些修改
某次在使用pull命令拉取代码的时候报这个错,字面意思就是一些untracked文件将会被此次合并操作覆盖掉,也就是,想合并代码就需要先删除这些文件,删除命令是:git clean -d -fx,这个命令会将所有未track过的文件删除,包括.gitignore文件里面指定的文件夹和文件,需要慎用;其中
还有其它命令形式:
通常建议使用git clean -f和git clean -df两个命令
git clean经常和git reset --hard一起结合使用. 记住reset只影响被track过的文件, 所以需要clean来删除没有track过的文件. 结合使用这两个命令能让你的工作目录完全回到一个指定的的状态
某个新加入的小伙伴在push代码的时候遇到了这个错误
remote: GitLab: You are not allowed to push code to protected branches on this project.
To http://code.admaster.co/social-base/buzzextractor.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to “xxxxxxxxx”
看英文意思就是不允许你往这个工程受保护的分支上提交代码
看起来是被拒绝了,其实就是没有master分支的权限,一般这个分支普通开发者是不能提交代码的,如果需要权限需要git管理员开通
在某次push代码的时候,报了这样一个错
error: failed to push some refs to 'xxxxxxxxxxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
字面意思是本次更新被拒绝了,因为当前分支的tip是在对应远程分支的后面,所以在push之前先要整合远程修改
其实意思就是远程分支有更新了,但是本地分支没有先合并这些修改就去push,这样是不行的
解决办法:
使用强制push的方法:git push -u origin master -f ;这样会使远程修改丢失,一般是不可取的,尤其是多人协作开发的时候
先将远程修改拉下来,再push代码
$ git pull origin master
$ git push -u origin master
某次使用push的时候报错如下
error: failed to push some refs to 'http://xxxxxx.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
意思是远程工程有本地工程没有的更新,需要先合并再提交
所以解决方法就是先使用git pull更新代码再使用git push提交代码
情况是我本地新建了一个工程,然后写了一些代码,想把它推送到git上一个毫不相关的仓库上(可以是新建的或者已经存在的),怎么操作呢?见下方
如果远程仓库是空的,也就是只是一个空仓库,那么直接在关联仓库地址后可以直接将分支推送到远程仓库,即
git remote add origin git仓库地址执行后,就可以使用如下命令将代码推送到远程仓库对应的分支,实际上就是在远程仓库新建一个对应的分支
git push --set-upstream origin master
在%HOME%目录中,一般为C:\users\Administrator,也可以是你自己创建的系统用户名目录,反正都在C:\users\xxx中;由于在Window中不允许直接创建以"."开头的文件,所以需要借助git bash进行,打开git bash客户端,进入%HOME%目录,执行如下命令:
touch .git-credentials
vim .git-credentials
https://{username}:{password}@github.com
注:第一行是用于创建文件.git-credentials,第二句是用git bash内置的vim工具编辑此文件;这里进入vim后需要按"a"进入编辑模式,按第三行的模版键入git信息,之后按下ESC退出编辑模式,再输入:wq!(wq!是保存并退出,vim里还有一个是q!,不保存直接退出),回到git bash,再输入以下命令:
git config --global credential.helper store
此时重启git bash,再使用push就不需要输入用户名和密码了
在团队多人开发时,经常要查看日志信息,所以这时候如果每个提交者的名称不清晰或者很乱,没办法一眼看出来是谁提交的那就很头疼了,所以就需要每位开发者在git终端中设置下自己的用户名(也可以配置下邮箱)
git config user.name "myname"
git config user.email "[email protected]"
// 查看当前代理设置
git config --global http.proxy
//设置HTTP代理
git config --global http.proxy 'http://127.0.0.1:1080'
//设置HTTPS代理
git config --global https.proxy 'http://127.0.0.1:1080'
# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy
config 配置有system级别 global(用户级别) 和local(当前仓库)三个
使用git config --list查看所有配置信息
打开远程git仓库可能会看到这样一个提示信息
git You won't be able to pull or push project code via SSH until you add an SSH key to your profile
这是因为远程的代码管理是基于SSH的,而本地用的是Http的,所以要使用远程的Git仓库则需要SSH的配置,生成公钥和私钥,实现本地和服务器的认证
首先需要配置下user name和email:
$ git config --global user.name "you name"
$ git config --global user.email "you email"
然后使用如下命令
ssh-keygen -t rsa -C "you email"
上面三个箭头处直接敲回车就行了,这样就在如图所示的目录生成了两个文件
第一个是私钥,保存在本地,第二个是公钥,最后就是把公钥文件的内容复制到GitLab服务器,如下
最后点击add key就可以了
git默认使用vim进行文本编辑,比如在commit的时候,或者进行pull合并代码的时候会进入vim编辑器输入信息,那具体应该怎么输入信息呢?
首先进入vim的时候默认是命令行模式,这时候你不管怎么弄都没办法输入内容,不知道的还以为自己电脑出问题了;
这时候就需要进行如下操作:
参考文章
https://git-scm.com/book/zh/v2
http://gitbook.liuhui998.com/4_9.html
https://blog.csdn.net/NEUQ_zxy/article/details/75267997
https://www.cnblogs.com/kevingrace/p/5690241.html