可到官网直接下载安装git
然后在开始中找到git bash点击出现一个命令行工具,命令行输入以下代码:
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
填写自己的名字和邮箱。
接下来创建版本库(仓库):
在合适的地方新建一个文件夹,这个文件夹里的所有文件都能被git管理
mkdir learngit
cd learngit
然后目录变成可以用git管理的目录:
git init
这个命令之后会新建一个.git目录,这个目录是隐藏的
把文件添加到版本库
版本控制只能跟踪文本的改动,比如上一次改动了哪些地方,而二进制文本是没办法跟踪的,只能将改动的地方串联起来,比如一个图片文件从100k变成了120k,只知道这些,改动了什么地方是不知道的,所以想要跟踪文本要使用纯文本
新建一个readme.txt文件,在文件中添加一些文字,文件的默认编码为utf-8,,为了和其他的平台不产生冲突
将文件添加到仓库:
git add readme.txt
将文件提交到仓库:
git commit -m "wrote a readme file"
-m后面说明是本次提交说明,可以输入任意内容
commit一次可以提交很多的文件,所以可以add很多的文件
git add file1.txt
git add file2.txt file3.txt
git commut -m "add 3 files"
现在添加了一个文件之后,改动文件的内容,然后在git中输入以下的命令:
git status
得到了以下的结果:
git status 命令告诉我们仓库当前的状态,告知我们readme.txt被修改过了
git diff readme.txt
查看文件修改的内容
在修改了之后,再次将文件添加到仓库:
git add reame.txt //添加文件到仓库
git status //查看当前仓库状态
git commit -m "add distrubuted" //将文件提交到仓库
再次查看仓库状态 git status ,提示没有需要提交的文件,目录是干净的
版本退回
使用命令git log 查看历史记录
git log
git log显示从最近到最远的提交日志,如果输出的信息太乱了,可以添加参数--pretty=oneline:
其中显示的一串数字是commit id(版本号)
将当前的readme.txt退回到上一个版本,在git中使用HEAD来表示版本,其中HEAD^表示上一个版本,HEAD^^表示上上个版本,上100个版本是HEAD~100,git reset 命令将文件退回到以前的版本:
git reset --hard HEAD^
cat 查看一个文件的文件内容:
cat readme.txt
然后你会发现文件已经退回到前面的版本了
git log查看日志,发现最新的那个版本的信息已经看不到了,只要当前窗口没有关掉,那么就可以找回其他的被退回的版本
在找回时要添加版本号的前几位,因为git会自己寻找相应的版本的
cat readme.txt的内容
想要退回到哪一个版本,只要跟上版本号就可以了
如果将窗口关掉了,找不到版本号了,git reflog记录了每一次的命令
git reflog
不要忘记了HEAD指向的是当前的版本
工作区和暂存区
工作区指的就是操作文件的一个目录,如当前的learngit
工作区有一个隐藏的目录.git,这个不算工作区,是git的版本库
版本库里有很多东西,其中最重要的就是叫做stage的暂存区,还有git为我们自动创建的第一个分支master,以及指向master的一个指针HEAD
使用git add将文件添加到仓库的时候实际上是将文件提交到暂存区
使用git commit将文件提交到仓库时是将暂存区的的文件提交到当前分支
因为在创建git版本库时,系统会自动为我们创建一个master分支,所以git commit是向master分支提交修改
可以将其简单的理解为,将要提交的文件放到暂存区,然后一次性提交修改
管理修改
为什么说git比其他的版本控制系统设计更加优良呢,那是因为gitl跟踪的是修改而不是文件
git diff HEAD -- readme.txt //查看工作区版本和版本库最新版本的区别
注:git add的文件是提交到暂存区 git commit是将放置在暂存区的所有文件一次性提交到工作区
撤销修改
git checkout -- file可以丢弃工作区的修改
git checkout -- readme.txt
git checkout -- readme.txt 意思是将readme.txt在工作区修改全部撤销,这里有两种意思:
1. readme.txt被修改之后还没有放到暂存区,现在撤销修改就回到和原来版本库的版本一模一样
2. readme.txt被添加到了暂存区,但是在此之后又对文件进行了修改,撤销修改之后回到添加到暂存区的版本
总之就是将文件回到git add或者git commit时的状态
git reset HEAD file
也可以将暂存区的修改退回到工作区
如果将不需要的内容提交到了工作区,那么可以退回到上一个版本,但是这个的前提是还没有将本地版本库推送到远程
删除文件
在git中删除也是一个修改操作
touch text.txt //新建一个文本文件
rm text.txt //删除文件
这个时候,git知道你删除了文件,工作区和版本库不同了,所以 git status 告诉我们哪些文件被删除了
现在有两个选择,一是从版本库中删除该文件(git rm file),并且 git commit
如果误删了文件,还可以恢复 git checkout -- text.txt 这个是从版本库中恢复文件,如果版本库中的文件也删除了那么就要到回收站去找了
远程仓库
利用github获取一个免费的git远程仓库,为github添加一个ssh秘钥,保证这台电脑git仓库里的东西可以推送到github上
首先在git bash中创建ssh key(获得的秘钥可以在用户主目录(C:/user/Adminstrator目录)下的.ssh目录下看到,一个私钥,一个公钥)
在git bash中输入如下代码:
ssh-keygen -t rsa -C "youremail@example.com"
然后一直默认,可以在.ssh目录下看到两个秘钥,将id_rsa.pub内的内容粘贴到github账号中添加的key中,如图:
github允许添加多个公钥,假如有多台电脑只需要把每台电脑的key都添加到github,就可以在不同的电脑上推送到github了
当然github是公开的,可供别人访问,所以较为私密的信息请不要传上去,如果想要私有,可以向github交点会员就ok了
添加远程库
先在github创建一个仓库
然后根据github的提示在git bash中输入如下代码:
git remote add origin https://github.com/HeLiangYu/learngit.git
git push -u origin master
将本地仓库的内容推送到github上
把本地内容推送到github上使用 git push 命令,实际上是把当前分支 master 推送到远程
由于远程库是空的,所以我们第一次推送 master 分支时,加上了 -u 参数,git不仅会把本地的 master 分支内容推送到远程新的 master 分支,还会把远程的 master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令
推送成功后,可以看到远程仓库github页面和本地仓库的内容已经一模一样了
从现在起,只要本地做了提交,就可以通过以下命令,将本地 master 将本地最新的修改推送到github,这个才是真正的分布式
git push origin master
分布式系统最大好处之一是在本地工作完全不用考虑远程库的存在,也就是没有联网也能正常工作
当有网络的时候在本地提交推送一下就完成同步了
从远库克隆
首先在github建立一个新的仓库,在仓库中建立一些文件,然后在 git Bash 中合适的目录下输入以下的命令:
git clone git@github.com:heliangyu/newGit.git
这段命令执行完毕之后,会在工程目录下生成一个新的目录newGit,这个目录下就是从远程仓库克隆过来的文件了
创建与合并分支
在版本退回里,每次提交,git都把它们串成一条时间线,这条时间线就是一个分支,master 分支是主分支,HEAD指向 master,而master指向提交
每次提交,master分支都会向前移动一步, 随着不断的提交,master分支也越来越长
git用master指向最新的提交,HEAD又指向master
HEAD指向的分支就是当前的 分支
如果使用git新建了一个分支为dev,git新建了一个指针git,指向master相同的提交交,再将HEAD指向dev,那么当前分支就是dev,当前分支是dev,那么对工作区的修改和提交就是针对dev了,随着每一次的提交,dev指针就向前移动一次,而master不变
如果在dev 上完成了工作,将dev合并master,只要将master指向dev的当前 提交就合并了
合并完成后,可以将dev指针删除掉,那么就只有一个master分支了
接下来创建分支dev,并且切换到dev:
git checkout -b dev
checkout 加上 -b 表示创建并切换,相当于以下两条命令:
git branch dev
git checkout dev
然后用以下命令查看分支:
git branch //列出所有分支,当前分支前带*符号
这样我们就能在dev分支上进行提交了
dev分支的工作完成了就可以切换到master分支了
git checkout master
这个时候会发现,前面修改的内容不见了,那是在dev上的,而现在是在master分支上,所以要将dev合并到master上
git merge dev
然后查看readme.txt文件,现在master和dev完全一样了
现在可以删除dev了
git branch -d dev
查看分支会看到只有一个分支了
因为创建、删除、合并分支非常快,所以最好是创建一个分支完成某个任务,合并掉之后再删除,这和直接在master上工作是一样的效果,但是过程更安全
解决冲突
当git无法自动合并分支事,要手动解决冲突,解决冲突后,再提交完成合并
vi readme.txt //进入文件,修改文件内容,修改完之后先esc退出 再输入wq保存并退出 输入i进入编辑模式
当分别在不同的分支上修改了文件,并且已经commit了,最后将其合并到master分支时会发生冲突
直接查看readme.txt:
git 用<<<<< ====== >>>>>来告诉我们文件中属于不同分支的内容
手动进行修改之后再进行合并
使用带参数的 git log 可以查看分支的合并情况
git log --graph --pretty=oneline --abbrev-commit
最后删除掉不需要的分支
git branch -d fe
分支管理策略
在合并分支时,git会使用 Fast forward 模式,但是使用这种模式的话,删除掉分支后会丢失分支信息
如果强制禁用 Fast forward 模式,那么在merge时就会生成一个新的commit,这样从分支历史上就可以查看到分支信息
git merge --no-ff dev // 禁用fast forward模式
git log --graph --pretty=oneline --abbrev-commit //查看历史分支信息
合并分支时,加上
--no-ff
参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而
fast forward
合并就看不出来曾经做过合并。
软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
工作还没有完成时,东西没有办法提交,git提供了一个stash功能,可以将当前工作现场“储存”起来,等以后恢复现场继续工作
git stash
现在,用git status
查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。
首先确定要在哪个分支上修复bug,假定需要在master
分支上修复,就从master
创建临时分支
修复完成后,切换到master
分支,并完成合并,最后删除issue-101
分支
查看刚才保存的工作现场:
git stash list
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
一是用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除;
另一种方式是用git stash pop
,恢复的同时把stash内容也删了
git stash apply //恢复工作现场
git stash drop //删除工作现场
git stash pop //恢复的同时删除
恢复指定的stash:
git stash apply stash@{0}
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash
一下,然后去修复bug,修复后,再git stash pop
,回到工作现场。
Feature分支
软件开发中,总有无穷无尽的新的功能要不断添加进来。
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
强行删除没有进行合并的分支(因为没有进行合并,如果强行删除,前面在这个分支进行的修改都将会被删除):
git branch -D <name>
多人协作
从远程仓库克隆时,git会自动将本地的master与远程的master同步起来,远程仓库默认是origin,要查看远程库的信息,使用以下命令:
git remote
或者使用以下命令显示更详细的信息:
git remote -v
推送分支就是将分支所有的本地提交推送到远程库。推送时,要指定本地分支,这样,git就会把该分支推送到远程库对应的远程分支上:
git push origin master //将本地的master分支推送到远程的origin分支上
git push origin dev //将本地的dev分支推送到远程的origin分支上
不是所有的分支都需要推送到远程分支上的,那哪些分支是需要推送的呢?
master分支是主分支,因此要时刻与远程同步
dev是开发分支,团队所有成员都要在上面工作,所以也要与远程同步
bug分支只用于在本地修复bug,就不用推送到远程了,除非有需要
feature分支是添加新功能的,看情况是否需要推送
抓取分支
现在你的小伙伴要在dev分支上进行开发,那么就需要创建远程的origin到dev分支到本地,用以下的命令创建本地dev:
git checkout -b dev origin/dev
现在他就可以在dev上进行修改了,并且时不时的dev分支push到远程
你的小伙伴已经向origin/dev分支推送新的提交,正好,你自己也要推送,提交了推送,发生了错误,产生了冲突
两个人都要向远程推送新的提交,所以产生了冲突,解决的方法很简单,只需要将远程的新的推送抓取下来,然后与本地的进行合并,再进行推送就可以了:
git branch --set-upstream dev origin/dev //指定本地dev和远程origin/dev的链接 指定之后再进行抓取
git pull //将远程最新的提交进行抓取
解决这个冲突的方法和解决合并冲突的方法是一样的,解决了冲突就可以合并了,提交然后再推送
创建标签
标签是一种类似与commit id 的东西,主要是为了人为的可以记录,看懂来进行版本查找
首先切换到需要打标签的分支上,然后打一个标签:
git checkout master
git tag name //name 指的是标签的名字
git tag //查看所有标签
默认的标签是打在最新提交的commit上的,但是如果现在是周五,而周一的标签没有打怎么办,只需要找到历史提交的commit id,然后打上就可以了:
git log --pretty=oneline --abbrev-commit
git tag v1.3 3498324(commit id)
tag是以字母来进行排列的,而不是以提交时间来进行排序的
可以用 git show tagName来查看标签信息
git show tagName
还可以创建带有说明的标签 -a指定标签名 -m指定说明文字,git show tagName还会显示标签的说明文字
操作标签
删除标签
git tag -d v1.0
因为标签是储存在本地,不会同步到远程,所以可以放心删除,如果要交标签推送到远程可以使用以下命令:
git push origin tagName
或者一次推送所有全未推送的标签
git push origin --tag
如果标签已经推送到远程,那么删除会麻烦一些,首先删除本地标签
git tag -d v1.0
然后再从远程进行删除,用的也是push命令
git push origin :refs/tags/v1.0
注:这些内容都只是作为自己学习之用,也是从别的网站上一步步学习的,详细的内容,如忽略特殊文件、配置别名、搭建git服务器等等以及其他更详细的内容请转到廖雪峰的官方网站进行查看