git快速入门
一、git的安装
目前我们移动组主要是Windows版本和Mac版本
1、Windows版本
直接前往git官网下载msysgit安装包(http://msysgit.github.io/)进行安装即可,安装流程和一般的windows软件的安装流程差不多,没什么区别。
2、Mac版本
Mac已经自带了git,无需安装。
二、配置git提交的用户名和邮件
这样做的目的是为了在git的log日志里面可以清楚的区分出每次的提交人是谁,以防日后出了问题能够立马清晰准确的定位出是哪个屌丝挖的坑,操作步骤:
1、Windows
随便在哪个空白位置右键,然后——》git bash,调出git的命令控制台。
2、Mac
打开Terminal终端即可。
输入以下命令:
$ git config --global user.name "Your Name(用户名)"
$ git config --global user.email "email@example.com(邮箱)"
这里简单的说明一下,加上--global参数是表示配置的全局范围,针对所有的git项目而言的,当然也可以分别给某一个项目配置,进入到某个项目里面,去掉--global参数即可。
三、生成 SSHKey
git推荐使用SSH协议传输文件(代码),会生成一个公钥和私钥,公钥配置在服务端,每次可以省去验证,方便快捷。当然使用https协议也是可以的,只不过是每次都需要输入用户名和密码,相对来说比较繁琐。
步骤:任意空白处右键调出git Bash命令控制台,,如果是Mac系统,打开终端就行了,输入以下命令:
$ ssh-keygen -t rsa -C "youremail@example.com"
然后一路回车,使用默认值即可,应该是需要3个回车的,设置密码为空(注意按3个回车的时候别输入其他的,不然设置的密码不为空,你就等着每次提交输入密码吧),如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。一般这个id_rsa.pub里面的内容是要配到git服务器上面的(由统一的人去管理),然后我们就可以从服务器上面拿代码和提交代码了。
1、Windows系统
![](https://note.youdao.com/ynoteshare1/images/replace-img.png)
2、Mac系统
打开Terminal终端,
cd /Users/feizi/.ssh/
ls
cat id_rsa.pub
之后复制里面的内容并粘贴到github或者gerrit或者码云这一类的代码管理系统的SSH公钥配置的地方即可。
四、获取代码与提交代码
首先给大家介绍几个概念,一个是本地worksapce工作区,一个是stash暂存区,一个是localRepository本地库,一个是remoteRepository远程库。
![](https://note.youdao.com/ynoteshare1/images/replace-img.png)
![](https://note.youdao.com/ynoteshare1/images/replace-img.png)
1、从git服务器下载代码到本地
git clone ssh://xxxxxxx@www.dreamtech.com.cn:29418/mlds
2、查看远程分支和本地分支
查看远程所有分支
git branch -a
如果你只想看本地分支
git branch
3、切换分支,创建分支,删除分支
只切换分支
git checkout dev
只创建分支
git branch dev
删除分支,(注意:这个需要先切换到其他的分支,如master分支,再执行以下的命令)
git checkout master
git branch -d dev
4、创建分支并且切换分支
基于远程分支创建本地分支并且切换到该本地分支,基于远程dev分支在本地创建一个dev分支,并且切换到dev分支。
git checkout -b dev origin/dev
或者:
git checkout -b dev
5、暂存本地工作区的修改
git add -A
通常用("."代表所有文件,注意"."前面的空格)
git add .
6、提交暂存区的内容到本地库中
git commit -m "注释"
7、抓取远程库最新提交的代码
git fetch origin dev
或者
git fetch
git fetch是简写(git 会自动搜索和当前分支名相同的远程分支名)
8、将本地修改与远程进行合并此时,若遇到冲突,需要先手动解决冲突(例如在eclipse中先解决冲突,再执行合并)
git rebase origin/dev
这个时候如果出现了冲突,就先解决冲突,冲突解决完之后,需先执行git add -A 命令,然后再执行git rebase --continue继续合并
9、安装changeId自动生成hook
注意:前面已经提过了,因为我这里使用了gerrit代码审查工具,所以每个人提交的时候就必须要先生成这个changID值,如果没有这个changID,则不能到gerrit代码审核工具中进行代码审核操作了。。而gerrit代码审查工具的存在就没有意义了。
操作步骤:进入到工作空间(workspace)中的仓库目录(比如说mlds),然后调出git bash控制台,输入如下命令:
scp -p -P 29418 username@www.dreamtech.com.cn:hooks/commit-msg .git/hooks/
10、将本地仓库中的代码push推送到远程仓库中
这里需要注意:
我们也可以直接用命令 git push origin saas 将代码直接push到远程代码仓库,但是由于现在我们这边是使用了gerrit代码审查工具,所有不能直接这样推送,必须使用git push origin head:refs/for/saas这个命令将代码推送到gerrit服务器上,然后我们再登录到gerrit中(会有一个web页面供我们操作)进行审核之后,执行最后合并,此时如果报错的话 有可能是因为你的changID 没有生成,使用之前介绍的命令生成changID。
最后再执行:
git push origin HEAD:refs/for/dev
或者git push origin head:refs/for/dev
11、登录到gerrit服务器中,进行代码审核,然后执行合并(这一步先不管,专人统一审核,合并提交代码到远程中央仓库)
五,撤销修改
1、场景一:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,使用
git checkout -- filename
通常用("."代表所有文件,注意"."前面的空格)
git checkout -- .
2、场景二:当你不但改乱了工作区的某个文件的内容,而且还提交到了暂存区(在本地执行了commit提交,但是
还没有commit提交到远程服务器)时,想丢弃修改,分两步:
第一步使用命令
git reset HEAD filename
通常用("."代表所有文件,注意"."前面的空格)
git reset HEAD .
就又回到了场景一
第二步再按照场景一的步骤操作
3、场景三:已经提交了和不合适的修改带版本库时,想要撤销本次修改,则可以使用版本回退,但是前提是还没有推送push到远程库
六、版本回退
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令
git reset --soft commit_id
或者
git reset --soft HEAD^
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
七、git stash 用法
关于Git Stash的详细解释,适用场合,这里做一个说明:
当前工作区内容已被修改,但是并未完成。这时Boss来了,说前面的分支上面有一个Bug,需要立即修复。可是我又不想提交目前的修改,因为修改没有完成。但是,不提交的话,又没有办法checkout到另外的分支。此时用Git Stash就相当于备份当前工作区了。然后在Checkout过去修改,就能够达到保存当前工作区,并及时恢复的作用。
之后,另一个版本的bug修复完毕之后,再使用checkout切换回之前的分支,然后再使用git stash pop 命令或者git stash apply命令就又可以恢复回来了。
git stash save "备注说明"
备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。
git stash pop
从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。
git stash list
显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
git stash clear
清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。
八、git如何放弃所有本地修改
git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态 git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。 git reset --hard HASH #返回到某个节点,不保留修改。git reset --soft HASH #返回到某个节点。保留修改
九、Git只更新远程库中的单个或者指定的文件
在开发过程中,我们有的时候并不需要更新远程所有的文件,而只需要更新某一个或者说特定的文件,如何操作呢?
SVN更新单个文件只需要svn up file/to/updat,非常简单,而且没有任何歧义。
但是git由于在远程服务器和本地都有一个代码库,这样只更新单个文件的话比SVN稍微要麻烦一点。
1、如果想拿远程git服务器上的最新版本(或者某个特定版本)去覆盖本地的修改,可以使用git pull命令,
但是这样会全面更新本地代码库和工作拷贝。
2、如果想放弃本地工作拷贝所做的修改,可以使用git checkout filePath命令,但该命令只能用本地库覆盖你的工作拷贝,并不能取得远程版本的更新。
所以,正确的方法应该是先更新本地库(但是不更新工作拷贝),然后用本地库来更新单个的工作拷贝文件。
如,假设说开发小伙A在本地新增或者是修改了某个文件file1,然后提交到远程库了,之后开发小伙B想要拿到这个file1文件,(注意场景:这里是只想拿到这一个文件file1,小伙A有可能提交了多个文件),那么小伙B这边可以这么做:
第一步,抓取远程库最新修改:
git fetch
第二步,指定某个文件进行更新:
git checkout origin/dev -- filePath
具体示例:
假设file1文件的路径为:
code/src/main/java/com/zxy/mlds/base/constant/APIMessage.java
git fetch
git checkout origin/saas-8.1-snapshot -- code/src/main/java/com/zxy/mlds/base/constant/APIMessage.java
十、 分支的合并
假设我们当前的版本有一个master主干分支,同时还有一个dev开发分支,因为通常情况下我们做开发都是在dev分支下进行的开发,之后开发完成后需要将dev分支开发的功能同步到master主干分支上,也就是合并到master分支上,那么怎么操作呢?
1、首先切换到需要合并的分支上,打个比方说:现在我们需要将dev分支合并到master主干分支,第一步:首先我们需要切换到master主干分支上
git checkout master
2、为了保证当前的本地master分支的内容与远程服务器中master分支的内容保持同步,我们需要先同步一下代码,执行:
git pull origin master
通常我们会拆成两个步骤来完成:
git fetch origin master
或者
git fetch
git rebase origin/master
3、将dev分支合并到当前master分支
git merge dev
或者
git merge --no-ff dev
4、此时如果在合并的过程中出现了冲突,则需要先解决冲突,解决方法同svn差不多
5、冲突解决完之后,再继续执行合并操作
git add -A
git rebase --continue
6、合并成功之后,我们再将master分支push推送到远程库中即可
git push origin master
十一、 如何合并某个分支中的一个或者是几个commit(s)提交
git cherry-pick 可以选择某一个分支中的一个或者是几个commit(s)来进行合并操作。
在实际应用中,我们可能会遇到这样的情况:例如,假设现在我们有个稳定版本的分支叫做release,另外还有一个开发版本的分支叫做dev,然后我们在dev开发分支里面修改了一些东西(新增了几个个功能,或者是修复了几个bug等等),之后commit了几个(这里注意是几个)更新操作(也就是提交到了本地库),但是后来我们发现同样需要在release分支上同步应用某个更新,我们不能直接将release分支和dev分支执行合并,因为这样将会导致稳定版本混乱,但是确实又想增加一个dev分支中的某个功能到release分支中来,那么这时我们就可以使用cherry-pick命令来解决这个问题了,就是对已经存在的commit进行再次commit(提交)操作。
简单用法:
git cherry-pick <commit_id>
注意:当执行完cherry-pick以后,将会生成一个新的提交,这个新的提交的哈希值和原来的不一致,但标识名是一样的。
1、首先,切换到dev开发分支
git checkout dev
2、然后找到dev分支的commitId 38361a6(说明:本来commitId是38361a68138140827b31b72f8bbfd88b3705d77a这么多位,但是可以只取前7位就行了。使用git log命令可以查看提交的commitId)
git log
commit 38361a68138140827b31b72f8bbfd88b3705d77a
3、之后再次切换回release分支
git checkout release
4、更新一下release版本的代码,保持与远程仓库的同步
git fetch origin release
git rebase orgin/release
5、执行cherry-pick命令,同步dev分支的修改代码
git cherry-pick 38361a6
6、如果顺利,就会出现下面这段提示,当然也有可能不出现这段提示,只要没报冲突,则说明代码同步成功了。
Finished one cherry-pick
# On branch old_cc
# Your branch is ahead of 'origin/old_cc' by 3 commits.
7、如果在cherry-pick 的过程中出现了冲突就手动解决冲突,解决完冲突之后根据提示继续执行同步。
git add -A
git cherry-pick --continue
8、最后push到远程仓库。
git push origin release
十二、一个完整的团队开发流程
1、git clone ssh://xxx@www.dreamtech.com:12256/xxx
2、git checkout -b dev origin/dev 或者 git checkout -b dev
3、git status
4、scp -p -P 29418 username@www.dreamtech.com.cn:hooks/commit-msg .git/hooks/
(只需执行一次,第一次执行即可,后面这一步就不需要了)
5、git add -A 或者 git add .
6、git commit -m "注释"
7、git fetch origin dev
8、git rebase origin/dev
这个时候如果出现冲突,注意出现冲突只可能会是在合并(rebase)时出现冲突,那我们就直接解决冲突即可,解决完之后,再依次执行:
git add -A
git rebase --continue
9、git push origin HEAD:refs/for/dev
或者如果远程库(gerrit仓库)只是一个空的仓库的话,这就需要先将本地库的代码关联到gerrit远程库(即将本地库与远程库建立映射关系),之后再推送上去。执行以下命令:
git remote add origin ssh://xxx@www.dreamtech.com:12256/xxx
git push -u origin HEAD:refs/for/master
或者如果不走代码审核流程则可以直接使用
git push -u origin master
这里加了-u参数,首次推送的话需要加上这个-u参数,以后都不需要了。
十三、一些拓展,详见wiki
1.从git服务上门下载代码到本地
git clone ssh://xxxxxxx@www.dreamtech.com.cn:29418/2b/zxy-cloud
2.查看远程分支和本地分支
git branch -a 如果你只想看本地分支 git branch
3.切换分支
git checkout dev 切换到远程分支dev,并且在本地创建一个分支名为dev
4.提交代码到远程
git status 查看下你更改的文件有哪些
git stash 暂存本地变更的代码,不要以为找不回了。
git fetch 拉去远程的代码到暂存区
git rebase 合并你拉去的暂存区的代码和本地代码进行合并
git stash pop 还原你本地变更的代码,这里可能产生冲突,解决即可,类似svn。如果你不想解决冲突,要以远程为主,那就采用git checkout – 你要还原的文件
git status 查看你更新的文件
git add 你要提交的文件 这里可以采用通配符的形式,如 git commit add src/main/java/com/*
git commit -m '注释' 提交你要提交的代码到暂存区,这个时候还没有到远程
git push origin head:refs/for/分支名 这个是才是提交到你远程分支
登录gretter网站 http://www.dreamtech.com.cn:90/#/ 指定审核人进行审核你的代码
5.提交回滚
git log 查看提交日志,找到你要会滚的日志的commitId
git reset --soft commitId 回滚到你提交点,保留本地的修改代码 修改完成后,走提交流程
git reset --mixed commitId 回滚到你提交点,保留本地的修改代码 修改完成后,走提交流程
git reset --hard commitiId 回滚到你提交点,丢弃本地的修改代码 修改完成后,走提交流程
以上两条命令,根据情况二选一即可
6.追加本地提交
有时候我们提交到本地,还没有推送到远程的时候,如果你忘记了和修改了,又想提交代码,可以使用追加提交
git add .
git commit --amend 修改提交日志,退出即可
7.修改远程分支和本地分支的映射地址
git remote -v 查看你远程的映射关系 一般名字都叫origin
git remote rm origin 删除远程分支和你本地分支的映射,不要担心,不是删除远程分支,相当于删除linux里面的软连接引用
git remote add 远程仓库名 远程仓库地址 添加新的远程分支映射 如 git remote add origin ssh://xxxxxxx@www.dreamtech.com.cn:29418/2b/zxy-cloud
git fetch --all 拉去远程分支信息 这个时候用 git branch -a 你就可以看到新远程分支的信息了
这个应用主要用到,我们把一个项目向迁移到另一个远程分支里面去,以前我们是修改.git文件里面的内容去做,个人推荐命令
8 日志查看
git log 查看日志
git log -3 只列出最近三次的提交历史
git log -p 会显示出每次提交做了哪些改动
git shortlog -s -n 会显示出总的提交次数
9 比较差异
git diff 比较了工作区与index的差异
git diff HEAD 比较了工作区与仓库中最近一次的提交间的差异
git diff --cached 比较了index与仓库中最近一次的提交间的差异
git diff HEAD^ HEAD 比较了当最近的这次提交与上一次提交之间的差异
git diff 指定的分支 比较了当前分支的HEAD与指定分支的HEAD之间的差异
git diff 分支1..分支2 比较了分支1到分支2之间的变动
十四、如何将本地的代码push到github仓库
1、注册GitHub账号以及创建仓库
登录gitHub官网注册gitHub账号,登录成功之后找到Create a New Repository创建仓库(免费用户只能建公共仓库),之后会出现一些仓库的配置信息,这里只需填写一个仓库名就可以了,填写完直接点击“Create repository”创建按钮即可。
![](https://note.youdao.com/ynoteshare1/images/replace-img.png)
2、之后就根据github的帮助提示一步步操作就可以了。
![](https://note.youdao.com/ynoteshare1/images/replace-img.png)
这里注意:一种是本地还没有仓库,需要创建(git init)一个仓库,一种是本地已经是一个git仓库了,需要将本地库推送到github远程仓库中去。分别对应上面的两种情况,直接根据提示命令一步步操作即可。
将本地的代码推送到远程gerrit仓库的步骤:
假如说现在你本地有一个project,现在需要将本地的project里面的代码提交到远程服务器仓库进行版本管理,并且需要经过gerrit审核。那么可以这样做:
1、登录gerrit的web界面,使用有权限的账号(比如admin管理员账号)登录,并且创建一个project。例如:创建一个叫2c/zxy-mobile的project
![](https://note.youdao.com/ynoteshare1/images/replace-img.png)
2、使用有权限的账号进行登录,设置其他人员(比如开发人员)的访问权限,不然的话没有权限拿代码
![](https://note.youdao.com/ynoteshare1/images/replace-img.png)
3、首先打开git bash控制台,cd到本地的project项目的根目录里面去
4、初始化仓库
git init
5、暂存工作区修改内容(在执行这个操作之前需要新建.gitignore忽略文件,忽略部分不需要提交的配置文件,这样这些文件就不会被git管理了)
git add -A
6、生成changeId
scp -p -P 29418 ruanpeng@www.dreamtech.com.cn:hooks/commit-msg .git/hooks/
6、提交代码到本地库
git commit -m "init repository"
7、将本地仓库与远程仓库进行关联起来
git remote add origin ssh://ruanpeng@www.dreamtech.com.cn:29418/2b/zxy-mobile
8、抓取远程库的代码(因为之前已经在gerrit上面新建了一个空的仓库,日志里面会记录一次提交)
git fetch origin master
9、合并一下代码(虽然远程是一个空的仓库,最好还是执行一下这个操作,这个时候git会将两次日志通过线性关联起来)
get rebase origin/master
10、将本地的代码推送到远程gerrit仓库里面,这里加上了-u参数,以后推送都不需要了,
git push -u origin HEAD:refs/for/master
这个是走了gerrit审核,如果不想走gerrit审核的话,就直接使用以这行命令就行了:
git push -u origin master
11、创建远程dev分支:
git push origin master:dev
12、基于远程dev分支创建本地dev分支
git checkout -b dev origin/dev
分支的合并:
假设现在有两个分支,一个master分支,一个dev分支,现在dev分支修改了新的东西,然后需要将这些新的代码同步到master分支上面去,操作步骤如下:
1、首先切换到master主干分支,
git checkout master
2、执行一个pull命令,保持master目前是最新版本
git pull origin master 或者git pull
e
建议使用
git fetch origin master
git rebase origin/master
3、合并dev分支到master分支上
git merge --no-ff dev
4、推送master本地分支代码到远程分支
git push origin master
创建远程dev分支:
git push origin master:dev
刷新远程分支:
git fetch -p
基于远程dev分支创建本地dev分支
git checkout -b dev origin/dev
如何删除分支(包括远程分支和本地分支)
首先在gerrit上面删除远程dev分支
再在git bash中使用
git fetch -p
刷新远程分支库
再删除本地dev分支
git branch -D dev
git创建分支
1、先切换到需要创建分支的版本下面,比如说dev分支
git checkout dev
2、然后基于dev分支再创建分支
git checkout -b dev_1.0
3、之后,将本地分支推送到远程仓库
可以先尝试着pull
git pull origin dev1.0
如果失败,可以继续执行
git push origin dev1.0
推送到远程仓库,ok,分支创建完成。之后我们再登录远程仓库,比如说github再验证一下,可以看到dev1.0分支已经存在了,说明dev的分支创建成功。
1、假如github上面有一个分支(master主分支和dev分支),已经与一台电脑进行了关联(即这台电脑上两个分支都存在),然后需要在另一台电脑上进行同步(另一个小伙伴需要开发),可以这样做。
a、先执行git fetch origin dev 先抓取最新分支,
b、再执行git checkout -b dev origin/dev
c、git fetch origin dev
c、git rebase origin/dev