详细的git学习教程等在网上都有许多,如:
1.https://git-scm.com/【git官网】
2.https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000【廖雪峰老师的,讲的比较细,通俗易懂】
然后在这个学习过程中遇到一些问题记录下来,方便以后回顾:
- git是目前最先进的分布式版本控制系统
- BitMover公司收回Linux社区对BitKeeper的免费使用权
- 导致Linus使用C编写了Git
- 集中式:版本库是集中存放在中央服务器的,先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。最大的缺点还是必须要联网才能使用。
- 分布式:分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,但通常也有一台充当“中央服务器”的电脑,这个服务器的作用仅仅是用来方便“交换”大家的修改,因为可以两两电脑之间进行操作,所以不用联网也能使用。
- 安装git【Linux】:sudo apt_get install git
- 安装git【windows】:地址:https://git-scm.com/downloads,下载后默认安装即可,将git下的bin添加至环境变量中,或直接点击Bash.exe运行git
- 安装后的用户配置(表示你这台机器上所有的Git仓库都会使用这个配置) :
git config --global user.name ”xiong@ying”
git config --global user.email “xiong@example.com”
9.安装后的用户配置(这是对某个的版本库配置,比如建了一个文件夹test之后,使用cmd进入到该文件夹,使用git init创建文件test为仓库,这时使用以下就是对该仓库test进行的用户配置):
git config user.name ”xiong@ying”
git config user.email “xiong@example.com”
1、创建版本库(repository):版本库以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。进入cmd命令提示符,进入文件目录下,使用命令:git init 可创建版本库。
创建版本库后,默认会增加.git的一个文件,因为这个文件默认是隐藏的,所以我们无法看到。
另外为了能正确的使用和管理,文件名称不要为中文字符
2、工作区与版本库:
工作区:就是电脑里我们能看到的目录,比如刚才建立的TestGit文件目录
版本库:就是工作区中隐藏的.git目录
git add :将文件从工作区添加到暂存区中
git commit:将文件从版本库中提交到分支,(因为使用git init创建版本库时,默认就创建了master分支,所以这里也是默认提交到master分支):【使用git commit命令会把暂存区的所有文件提交至分支】
git commit -m “first commit”
git commit -m “second commit”
git log :用于查看提交(commit)历史
打圈的就是提交信息时的commit信息
使用一行来展示提交(commit)的log:
git log --pretty=oneline(注意等号左右不能有空格)。
git reflog :查看命令历史,以便确定要回到未来的哪个版本
版本回退:当我们已经从暂存区将文件提交到分支之后,通过git reset命令可以进行版本的回退
当前版本HEAD,上一个版本HEAD^ ,上上一个版本HEAD^^,往上100个版本HEAD~100
git reset --hard HEAD^ 回退到上一个版本
git reset --hard HEAD^^
git reset --hard HEAD~3
git reset --hard 109.... (版本号)
撤销修改:git checkout -- filename.txt:【“--”非常重要,如果没有就变成了“切换到另一个分支”的命令】【就是将分支中的文件放入到工作区或暂存区中】
有两种:
1.文件修改只在工作区中,即未做git add操作
2.文件修改并已经放在了暂存区中,即做了git add 操作,但未做git commit操作
用命令git reset HEAD filename.txt可以把暂存区的修改撤销掉(unstage),重新放回工作区,
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本,因为最新版相当于是在分支上的,所以使用HEAD就是撤回】
如果已经提交到了分支,即使用了git commit命令,那么就要用git reset 命令来回退了。
删除文件,可以手动到文件管理中删除,也可以使用命令操作:
rm filename.txt
这时工作区与版本库中的就不一样了,使用git status查看
git rm 命令表示版本库中也删除该文件
git rm filename.txt
如果在工作区是误删,可以使用git checkout -- filename.txt来将版本库中的撤销到工作区中
git checkout -- filename.txt
现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。
以下为一个具体的实例:
首先我在本地建议一个目录,名字为git,然后使用git init将目录变为版本库,然后再在git目录下建两个文件index.txt、test.txt
然后先到github.com中建立一个respository,名字为git
在GitHub上的这个git仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库,现在我们就将本地的git仓库的内容推送到GitHub中的git远程仓库中。
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;【git remote add origin git@github.com:fireporsche/git.git】
关联后,使用命令git push -u origin master第一次推送master分支的所有内容,这样推送时发现如下错误:
C:UsersxiongDesktopgit>git remote add origin git@github.com:fireporsche/git.git C:UsersxiongDesktopgit>git push -u origin master error: src refspec master does not match any. error: failed to push some refs to 'git@github.com:fireporsche/git.git'
通过上网查资料才发现【https://www.cnblogs.com/jeremylee/p/5715289.html】,这是因为我的版本库中文件为空,即没有将工作目录中的文件提交到版本库中,所以需要git add git commit命令进行提交,如下:
C:UsersxiongDesktopgit>git add . C:UsersxiongDesktopgit>git commit -m 'first commit' error: pathspec 'commit'' did not match any file(s) known to git.
又出现错误,大概意思就是说没有文件可commit,通过查询才明白【https://blog.csdn.net/huahua78/article/details/52330792】,原来在windows中要使用双引号,使用单引号无效,所以更改为git commit -m "first commit"就可以成功提交。然后继续git push -u origin master,有发现如下错误:
大概意思就是推送时,认证失败,通过查询【https://blog.csdn.net/huahua78/article/details/52330792】,才发现是需要ssh key的,下面进行ssh key的创建:
使用ssh-keygen -t rsa -C "1161137899@qq.com"生成ssh key
C:UsersxiongDesktopgit>ssh-keygen -t rsa -C "1161137899@qq.com" Generating public/private rsa key pair. Enter file in which to save the key (C:Usersxiong/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in C:Usersxiong/.ssh/id_rsa. Your public key has been saved in C:Usersxiong/.ssh/id_rsa.pub. The key fingerprint is: SHA256:h3oYUyuWol138R/GCt7aeGIn03Jvv523aSBlwtCXjp0 1161137899@qq.com The key's randomart image is: +---[RSA 2048]----+ | . . | | . . o | | . + = . | | o o * E | | . B S + = + | | o + B + + = . | | . . o . ..+ o | | . *+= ..=| | .oO.oo**| +----[SHA256]-----+
会在本地C:Users你的用户名.ssh生成文件夹,里面有id_rsa和id_rsa.pub两个文件
然后复制id_rsa.pub文件里面的内容,到https://github.com/settings/keys新建一个后如下图所示:
这时再使用git push -u origin master就能成功推送了:
C:UsersxiongDesktopgit>git push -u origin master Warning: Permanently added the RSA host key for IP address '52.74.223.119' to the list of known hosts. Enter passphrase for key '/c/Users/xiong/.ssh/id_rsa': Enter passphrase for key '/c/Users/xiong/.ssh/id_rsa': Counting objects: 4, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 351 bytes | 0 bytes/s, done. Total 4 (delta 0), reused 0 (delta 0) To git@github.com:fireporsche/git.git * [new branch] master -> master Branch master set up to track remote branch master from origin.
由于远程库是空的,我们第一次推送master
分支时,加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令【git pull origin master git push origin master】。
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改。
如上是先有本地库,后有远程库的时候,如何关联远程库,现在先创建远程库,然后,从远程库克隆
进入到要克隆文件的目录:
C:Usersxiong>cd C:UsersxiongDesktop #地址的第一种方式 C:UsersxiongDesktop>git clone git@github.com:fireporsche/learngit.git Cloning into 'learngit'... Enter passphrase for key '/c/Users/xiong/.ssh/id_rsa': warning: You appear to have cloned an empty repository. Checking connectivity... done. #地址的第二种方式 C:UsersxiongDesktop>git clone https://github.com/fireporsche/learngit.git Cloning into 'learngit'... warning: You appear to have cloned an empty repository. Checking connectivity... done.
然后在桌面就能看到learngit文件夹了
分支管理
创建分支:git branch dev
切换分支:git checkout dev
合起来:git checkout -b dev
场景:
切换到dev分支:git checkout dev
做更改后提交:git add test.txt git commit -m “first commit” 这时是提交到的dev分支
切换至master分支:git checkout master
将dev分支合并到master分支:git merge dev 将指定的分支合并到当前分支
合并完后删除分支:git branch -d dev
合并分支时,如果可能,git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息.
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
git merge --no-ff -m "merge with no-ff" dev
这样当我们删除了分支后,使用git log还能看到提交的版本号了
实践过程中遇到的一个问题:
我本地有master和yingcai分支,远程有master,develop,yingcai分支,然后我在本地先拉取master或develop的代码git pull origin develop后进行修改,然后进行代码的push即git push origin develop,但是会报以下错误:
通过同事的帮助,才发现本地每个分支必须与远程端一一对应,我本地的master分支是没有和远程的develop分支对应的,所以无法push到对应的develop分支:
git checkout -b develop origin/develop 【先在本地创建远程的develop到本地,并且切换到本地的develop分支】
git pull origin develop 【把远程develop的代码拉取下来】
git add . git commit -m "commit" 【进行代码的更改后进行提交】
git push origin develop 【把代码push到远程的develop分支】
bug分支:当我们接到BUG时,可以建立一个BUG分支进行BUG的修复,但是可能自己手上真正的工作还没有完成,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
git stash 这样使用git status查看工作区就是干净的,然后确定自己想要在哪个分支(比如master)下建立bug分支,按以上操作后提交bug的修复后删掉bug分支。
具体的操作:
本地工作的方式,当前分支为dev Git stash 【隐藏工作】 Git checkout master 【切换到master分支】 git checkout -b issue01 【创建并切换到bug分支】 Git add . 【对bug进行修复后进行代码提交】 Git commit -m “issue01” 【对bug进行修复后提交】 Git checkout master 【切换至master分支】 Git merge --no-ff -m "merged bug fix 01" issue01 【将bug分支与master分支合并】 Git checkout dev 【切换到dev分支继续进行工作】 Git stash list 【查看之前隐藏的内容是否存在】 Git stash apply 【恢复所有隐藏的内容】 Git stash apply stash@{0} 【恢复指定的stash内容,后面的stash@{0}是通过git stash list得到的】 Git stash drop 【删除stash的内容】 Git stash pop 【git stash apply+git stash drop】
feature分支:
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支
git checkout -b feature1 git add . git commit -m "commit" git checkout master #如果接到通知说不需要此功能了,直接删除该分支 git branche -d feature1 error: The branch 'feature1' is not fully merged. If you are sure you want to delete it, run 'git branch -D feature1'. #所以使用-D进行强制的删除 git branche -D feature1
多人协作:
当你从远程仓库克隆时,实际上Git自动把本地的master
分支和远程的master
分支对应起来了,并且,远程仓库的默认名称是origin
。
git checkout -b develop origin/develop#先在本地创建远程的develop到本地,并且切换到本地的develop分支 git pull origin develop #把远程develop的代码拉取下来 git add . git commit -m ‘commit’ git push origin develop#把代码push到远程的develop分支
-
查看远程库信息,使用
git remote -v
; -
本地新建的分支如果不推送到远程,对其他人就是不可见的;
-
从本地推送分支,使用
git push origin branch-name
,如果推送失败,先用git pull
抓取远程的新提交; -
在本地创建和远程分支对应的分支,使用
git checkout -b branch-name origin/branch-name
,本地和远程分支的名称最好一致; -
建立本地分支和远程分支的关联,使用
git branch --set-upstream branch-name origin/branch-name
; -
从远程抓取分支,使用
git pull
,如果有冲突,要先处理冲突