一张图简单了解下什么是git?
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
git工作流
克隆远程资源-本地修改-提交之前查看修改-提交修改-处理冲突-再次提交-撤回修改
git工作原理
工作区:就是你在电脑里能看到的目录。
暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。
他们之间是什么关系呢?
咱们打个比喻,更好理解一下这些关系。比如我们要修改一份重要文件或文件夹吧。
因为这份文件很重要,如果直接在这上面修改的话,万一改错了,可能无法复原是吧。
所以我们会先把这份文件克隆一份到一个目录下(就是你的仓库),然后你打开文件开始修改,这个目录就是你的工作区,你可以在这个目录下做任何修改操作,包括创建新文件,删除文件等等。
那么如果你要修改的文件有很多,那么你每修改一份就去覆盖原来的,可能不放心是吧,也可能忘记改了什么,也可能不想要之前修改的版本,那么比较保险的,你可能会把今天改的,昨天改的,刚才改的等等先在另一个地方暂存起来,做好改动标记,这就是暂存区。
当全部修改完成,放入到暂存区之后,再根据哪些确实要改动,再覆盖掉源文件。就成了新的一个版本文档了,这就是版本库。
快速入门
首先windows下安装git bash, linux安装git,安装教程百度很多。简单就不说了。
安装完成后,给自己配置一些基本信息,这样你以后项目都是用到这些信息。
$ git config --global user.name "youhailiang"
$ git config --global user.email "[email protected]"
查看配置信息
$ git config --list
或
$ git config user.name
创建本地仓库repository
git init #当前目录作为仓库
git init repo #设置repo目录为仓库
创建完成之后,进入仓库目录,运行ls -a 可以找到.git文件夹,说明创建成功了。
$ git add file # 当你修改完文件之后,执行后放入暂存区,可以使用通配符
$ git add * # 把当前目录下所有除.开头以外的文件放入暂存区
$ git commit -m '版本提交说明内容' #把暂存区的内容提交到版本库
那么如果你是要从远程仓库克隆项目到本地的话,使用git clone
$ git clone
$ git clone git://github.com/schacon/grit.git #会在当前目录创建仓库grit
$ git clone
$ git clone git://github.com/schacon/grit.git mygrit #仓库名mygrit
常用命令
创建仓库命令
$ git clone git://github.com/schacon/grit.git #克隆已经存在的仓库
$ git init #创建一个新的本地仓库
本地更新
$ git add [file1] [file2] ... #添加一个或多个文件到暂存区
$ git add . # 添加当前目录下的所有文件到暂存区
$ git rm [file] #将文件从暂存区和工作区中删除
$ git rm -f runoob.txt #如果这份文件已修改并放到暂存区,强制删除
$ git rm --cached
$ git status # 查询当前项目变动情况
$ git status -s # 简要的查询
$ git diff #当工作区有改动,临时区为空,diff的对比是“工作区与最后一次commit提交的仓库的共同文件”;当工作区有改动,临时区不为空,diff对比的是“工作区与暂存区的共同文件”。
$ git diff [file] #查看某个文件在工作区和暂存区的区别
$ git diff --cached [file] #查看某个文件在暂存区和版本库最后一次commit(HEAD)的区别
或
$ git diff --staged [file]
$ git diff HEAD #显示工作目录(已track但未add文件)和暂存区(已add但未commit文件)与最后一次commit之间的的所有不相同文件的增删改。
$ git commit -m [message] # 提交暂存区到本地仓库中
$ git commit [file1] [file2] ... -m [message] # 提交暂存区的指定文件到仓库区
$ git commit -a #修改文件后不需要执行 git add 命令,直接来提交
$ git commit --amend #修改上次提交的内容或说明
提交日志
$ git log #查看历史提交日志
$ git log --oneline #简洁查看
$ git blame
更新和发布
$ git remote -v # 显示所有远程仓库
origin ssh://[email protected]:2222/ericyou/autoplatform.git (fetch)origin ssh://[email protected]:2222/ericyou/autoplatform.git (push)
origin是远程仓库别名
$ git remote show [remote] # 查看某个远程仓库的信息
git remote show ssh://[email protected]:2222/ericyou/autoplatform.git
$ git fetch [alias] #去远程仓库获取它有你没有的数据,但不进行分支合并
$ git pull <远程主机名> <远程分支名>:<本地分支名> 等同于git fetch 和git merge,如果没有提供远程分支名,默认是master分支,如果没有提供本地分支名,默认是当前分支
$ git pull origin master:brantest #将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并
$ git push <远程主机名> <本地分支名>:<远程分支名> #将本地的分支版本上传到远程并合并; 如果远程分支名=本地分支名,可以省略远程分支名
$ git push origin master #将本地的 master 分支推送到 origin 主机的 master 分支
分支管理
几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。
$ git branch
$ git checkout
$ git checkout -b
$ git branch -av #列出所有存在的分支
$ git branch -d
分之合并
$ git merge test #把test分支合并到当前分支
合并冲突
两个已经提交的分支的相同文件相同位置的的不同操作进行了合并,冲突的产生前提是同一份文件,在你不知道其是否被操作的时候,你也进行了操作,然后提交就会产生冲突。
举例:
1,如果我在master分支创建一个文件并写入内容,然后提交之后,切换到另一个分支other,但是这个分支没有这个文件,这个时候把master分支合并到other分支,git merge master, 不会产生冲突,因为不满足同一份文件的条件,只有master才有这份文件。
2,如果master和other分支都有同样的文件,我在other分支修改了文件内容并提交,然后切换到master分支,再把other分支合并,git merge other,不会产生冲突,因为不符合两个不同操作,master并没有操作。
3,如果master和other分支都有同样的文件,我在other分支修改了文件内容并提交,然后切换到master分支,同样修改了相同位置的内容,并提交,这个时候进行合并会产生冲突,因为master在修改之前并不知道other也改了,而且是同一位置。
合并并不仅仅是简单的文件添加、移除的操作,Git 也会合并修改。
4,我在master分支修改了内容,但是other分支并没有修改,这个时候我合并other分支到master,不会产生冲突,这叫自动合并。
产生冲突之后,执行git diff可以看到如下文件,具体哪里产生了冲突。
一般情况下冲突后的文件会是:
<<<<<<<
other code
========
your code
>>>>>>>>your branch name
产生冲突的时候,一定要找当事人说清楚如何解决冲突,而不要随意拉取别的分支去试图解决冲突,或者覆盖文件。修改完冲突之后要重新add/commit/push
$ git branch
$ cat runoob.php
首先,我们创建一个叫做 change_site 的分支,切换过去,我们将 runoob.php 内容改为:
echo 'runoob';?>
创建 change_site 分支:
$ git checkout -b change_site
$ vim runoob.php
$ head -3 runoob.php
echo 'runoob';?>
$ git commit -am 'changed the runoob.php'[change_site 7774248] changed the runoob.php
1 file changed, 3 insertions(+)
将修改的内容提交到 change_site 分支中。 现在,假如切换回 master 分支我们可以看内容恢复到我们修改前的(空文件,没有代码),我们再次修改 runoob.php 文件。
$ git checkout master
$ cat runoob.php
$ vim runoob.php # 修改内容如下
$ cat runoob.php
echo 1;?>
$ git diff
diff --git a/runoob.php b/runoob.php
index e69de29..ac60739 100644--- a/runoob.php+++ b/runoob.php@@ -0,0 +1,3 @@+
$ git commit -am '修改代码'[master c68142b] 修改代码
1 file changed, 3 insertions(+)
现在这些改变已经记录到我的 "master" 分支了。接下来我们将 "change_site" 分支合并过来。
$ git merge change_site
Auto-merging runoob.php
CONFLICT (content): Merge conflict in runoob.phpAutomatic merge failed; fix conflicts and then commit the result.
$ cat runoob.php # 代开文件,看到冲突内容
echo 1;=======
echo 'runoob';>>>>>>> change_site?>
我们将前一个分支合并到 master 分支,一个合并冲突就出现了,接下来我们需要手动去修改它。
$ vim runoob.php
$ cat runoob.php
echo 1;
echo 'runoob';?>
$ git diff
diff --cc runoob.php
index ac60739,b63d7d7..0000000--- a/runoob.php+++ b/runoob.php@@@ -1,3 -1,3 +1,4 @@@
+echo 1;+ echo 'runoob';
?>
在 Git 中,我们可以用 git add 要告诉 Git 文件冲突已经解决
$ git status -s
UU runoob.php
$ git add runoob.php
$ git status -s
M runoob.php
$ git commit[master 88afe0e] Merge branch 'change_site'
现在我们成功解决了合并中的冲突,并提交了结果。
避免冲突
当远程仓库和本地仓库不一致时,在进行push操作时就会报错,这时候的做法:
1,在push之前,先把远程的代码拉取到本地新的一个分支
git fetch remoteName remoteBranch:newBranch
2,查看新的分支和本地分支的区别
git diff newBranch
3,将本地分支和新的分支合并
git merge newBranch [--allow-unrelated-histories]
注意:其中--allow-unrelated-histories是可选项,当报错“refusing to merge unrelated histories”时加上该选项就可以进行merge。 在进行pull操作时如果也报这个错误也可以加上这个选项。
4,将本地分支和新的分支合并
执行push操作
5,删除这个新的分支
git branch -d newBranch