您的位置:首页 > 其它

git学习--必须要会的版本控制工具

2014-08-30 21:40 501 查看

git基础

终端命令

mkdir新建目录

rm删除文件

rmdir删除目录

cd进入目录

pwd显示当前目录的路径

ls列出当前目录的内容

cat打开阅读文件

vi创建一文件,并编辑

:x当进入编辑界面,此命令是"保存并退出",记得先按下esc

git命令

将文件变成git仓库

$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/


把某一文件添加到git仓库

git add 1.txt

git add 2.txt

提交事务

git commit -m "这里是此次提交的描述"

注:add与commit的工作-----add是把文件放在stage(暂存区),commit是放入唯一的master(分支),分支的唯一标示是commit

工作区---->暂存区---->分支



查看仓库的状态,如果有文件修改了,他会告诉你,只是告诉你修改了,而不会告诉你哪里修改了

git status

要知道文件修改的具体内容

git
diff 1.txt

查看提交的历史

git log

查询命令历史

git reflog

穿梭至某个版本--版本对应commit id

git reset --hard commit_id

注意:git管理的是修改

第一次修改---->git add---->第二次修改----->git commit

这里实际上并没有将第二次修改提交!!

Git管理的是修改,当你用“git add”命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,

所以,“git commit”只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

所以应该是:第一次修改--->git add--->第二次修改--->git add--->git commit

总结:每次修改都要add到暂存区然后commit.

取消修改

情况一:在工作区修改了,未到暂存区

git checkout-- 1.txt//这样就回到修改前的状态

情况二:在工作区修改了,并add到了暂存区

git reset head1.txt//这样就把暂存区的修改撤销

git checkout-- 1.txt//再把工作区修改撤销

情况三:在工作区修改了,并add到了暂存区,并且commit到本地库中

利用之前的穿梭至某个版本回到之前版本,然后再执行上面两部操作.

情况四:在工作区修改了,并add到了暂存区,并且commit到本地库中,并且推送到了远程的版本库(后面会说)

完了,无论如何别人也看的到你的修改记录了.

删除文件

删除也是一种修改,但是不再使用git add 命令了

如下:

rm 2.txt

git rm 2.txt

git commit -m "delete 2.txt"

远程仓库-----GitHub学习

以github为例,由于github使用ssh加密传输,所以需要一点设置

1.创建ssh key

ssh-keygen -t rsa -C "youremail@example.com"


然后一路回车就行,如果想要密码的话自己输入,一般无需密码.

如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,

id_rsa.pub是公钥,可以放心地告诉任何人。

2.登陆GitHub,打开“Account settings”,“SSH Keys”页面:然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:



为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。

当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。

最后友情提示,在GitHub上免费托管的Git仓库,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放进去。

现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。

首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库:



在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:

比如我的地址是: https://github.com/mio4kon/wiki.git
根据github的提示,我们在本地执行下面命令:

git remote add origin https://github.com/mio4kon/wiki.git[/code] 注意你pwd的位置一定要是一个仓库.

下面,就可以把本地库的所有内容推送到远程库上:

git push -u origin master

用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

从现在起,只要本地作了提交,就可以通过命令:

git push origin master

=======================前面说的实际上是现有本地库,再有远程库,然后如何关联远程库=======================

=======================假定是从零开发,那么最好的方式是现有远程库,再从远程库克隆=======================

可以使用下面命令,将仓库内容克隆到文件夹中

git clone 地址

分支

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

弄清分支之前,先弄清两个术语

head
当前状态下最后一次提交,是索引

master分支(主线)

原先,只有一个master分支,那么每commit一次实际上是将head与master同时向前移动(Git用master指向最新的提交,再用HEAD指向master)

如果有两个分支呢?

下面是一组分支开发的流程图:









OK,原理了解了,我们就该命令行实现了

1.创建dev分支,然后切换到dev分支(-b) ------>单独用checkout是切换分支

git checkout -b dev

2.用git branch命令查看当前分支,他会列出所有分支(有星号的表示处在哪个分支上)

git branch

3.然后就在*号的分支上工作啦,比如add什么的.

此时master分支并没有修改.只是在dev分支上修改而已.====>对应图二

4.现在把dev分支合并到master分支上

git merge dev

5.合并完成后删除dev分支

git branch -d dev


分支命令总结:

查看分支:git branch

创建分支:git branch name

切换分支:git checkout name

创建+切换分支:git checkout -b name

合并某分支到当前分支:git merge name

删除分支:git branch -d name

解决冲突

假如有个feature1分支

现在,master分支和feature1分支各自都分别有新的提交,变成了这样:



这种情况下合并会产生冲突.

合并后记得手动把冲突解决,然后再add,commit

--no-ff合并分支模式

之前的合并没有加任何参数是默认快速合并,这种模式下,删除分支后,会丢掉分支信息。

--no-ff方式的merge,会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

git checkout -b dev

git add readme.txt

git commit -m "add merge"

git checkout master

git merge --no-ff -m "merge with no-ff" dev

因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

合并后,我们就可以用git log看看分支历史

不使用快速合并的方式,实际上合并如下图:



保存分支现场

假定正在dev分支处理,处理了一半,突然被要求解决一个bug.
应该做一个bug分支专门用来解决bug,但是dev分支怎么办呢?
先把工作现场git stash一下,然后去修复bug,修复后,再git
stash pop,回到工作现场。

此时正在dev分支,执行下面命令:

git stash

git checkout master	//切换到主线(假定在主线的分支上修复)


git checkout -b issue-101	//创建101号bug分支并切换

git add readme.txt
git commit -m "fix bug 101"	//修改完bug后add,commit

git checkout master				//切换到主线

git merge --no-ff -m "merged bug fix 101" issue-101	//将bug分支合并到主线

git branch -d issue-101				//删除bug分支

回到dev分支现场
有两个办法:

一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;

另一种方式是用git stash pop,恢复的同时把stash内容也删了:

git stash pop

当然:你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:

git stash apply stash@{0}


丢弃没有被合并过得分支

如果要丢弃一个没有被合并过的分支,可以通过git branch -D name强行删除。

多人协作

git remote -v	//可以查看远程库的信息

推送分支:就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上

git push origin master	//推送到远程主线分支


或者是

git push origin dev	//推送到远程dev分支(同时会在远程建立dev分支)


多人协作时,大家都会往master和dev分支上推送各自的修改。

现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆:

git remote add origin https://github.com/mio4kon/wiki.git[/code] 默认情况下,你的小伙伴只能看到本地的master分支。

现在,你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:

git checkout -b dev origin/dev		//将远程分支创建到本地

现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程

但是恰巧你也在dev上修改,此时如果要push到dev分支推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送

git pull

可能git pull也会失败,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接

git branch --set-upstream dev origin/dev	//与远程dev分支建立连接

git pull

此时已经本地合并了,但可能有冲突,解决下冲突,然后commit 再push

自定义git

git显示颜色

git config --global color.ui true	//让Git显示颜色,会让命令输出看起来更醒目




忽略特殊文件

在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
https://github.com/github/gitignore 这里有一些忽略模板,可以参考下

忽略文件的原则是:

忽略操作系统自动生成的文件,比如缩略图等;

忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;

忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

配置别名

有没有经常敲错命令?比如git status?status这个单词真心不好记。

实际上我们只需要敲一行命令,告诉Git,以后st就表示status:

git config --global alias.st status

当然还有别的命令可以简写,很多人都用co表示checkout,ci表示commit,br表示branch

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch

我们知道,命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。既然是一个unstage操作,就可以配置一个unstage别名

git config --global alias.unstage 'reset HEAD'		//这里有单引号,因为是词组

这样:

git unstage test.py	//实际上是:  git reset HEAD test.py


搭建远程git服务器

GitHub就是一个免费托管开源代码的远程仓库。
但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用。

搭建Git服务器需要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。

假设你已经有sudo权限的用户账号,下面,正式开始安装。

第一步,安装git:

sudo apt-get install git

第二步,创建一个git用户,用来运行git服务:

sudo adduser git


第三步,创建证书登录:

收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

第四步,初始化Git仓库:

先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:

sudo git init --bare sample.git


Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:

sudo chown -R git:git sample.git


第五步,禁用shell登录:

出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:

git:x:1001:1001:,,,:/home/git:/bin/bash

改为:

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell


这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

第六步,克隆远程仓库:

现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:

git clone git@server:/srv/sample.git


剩下的推送就简单了。

参考链接:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: