Git常用操作
配置账户
Copy git config --global user.name "lipengfei" #配置用户名
git config --global user.email "goodlpf00@gmail.com" #配置电子邮箱
ssh-keygen -t rsa -C "goodlpf00@gmail.com" #生成公钥和私钥对
cat ~/.ssh/id_rsa.pub #查看公钥信息
ssh git@bitbucket.org #测试ssh的密钥对 #在linux下,如果测试不通过,键入命令: add-ssh ~/.ssh/id_rsa
从本地仓库创建远程仓库
Copy git push --set-upstream ssh://git@github.com:RunAtWorld/$(git rev-parse --show-toplevel | xargs basename).git $(git rev-parse --abbrev-ref HEAD)
克隆仓库
Copy git clone git@github.com:RunAtWorld/quietalk.git #从远程克隆一个仓库
拉取操作
Copy git fetch origin #从远程仓库 origin 下载所有变化数据,但是不放到工作区
git merge origin/dev #将远程仓库中的dev分支与当前本地分支合并
git pull <远程主机名> <远程分支名>:<本地分支名> #相当于git fetch origin 和git merge origin/dev 两条命令的合并
git pull origin dev:master #拉取远程dev分支与本地master分支合并
提交文件
常用的操作
Copy git add . #添加当前文件夹下所有文件到下一次提交,并被跟踪
git commit -m "abc" #带信息"abc"提交一次变化到本地仓库
git commit -n #不带信息提交
git commit --no-commit #不带信息提交
git push #提交本地文件到远程仓库
更多操作
Copy git add 1.txt #添加1.txt到下一次提交,并被跟踪
git add . #添加当前文件夹下所有文件到下一次提交,并被跟踪
git add *.txt #添加所有txt文件到下一次提交,并被跟踪
git commit -m "abc" #带信息提交一次变化到本地仓库
git commit -am "abc" #带信息提交所有修改的文件变化到本地仓库,可以省略 git add 操作
git commit --amend #修改上一次提交
查看状态与日志
查看状态
Copy git status #显示当前git的状态
git remote -v #列出当前配置的远程库
查看日志
Copy git log #查看git日志
git log --after="2018-05-21 00:00:00" --before="2018-07-25 23:59:59" # 查看某个时间段日志
git log --oneline --since ="2018-07-19 00:00:00" --until=="2018-11-19 23:00:00" #单行查看某段时间的日志
git log --graph --oneline #点线图查看日志
git log --no-merges origin/dev #列出远程dev分支没有合并前的变化
分支
创建分支
Copy git branch #查看当前分支
git branch dev #创建dev分支
git checkout dev #切换到一个分支dev
git checkout -b dev #创建并切换到分支dev
git branch -m old_name new_name #本地分支重命名
删除分支
Copy git branch -d branch4 #删除一个本地分支branch4
git push origin --delete branch4 #删除远程分支branch4
合并分支
Copy git merge branch4 #将branch4分支与当前分支合并
查看分支
Copy git branch -r #列出远程分支
git branch -v #列出本地分支
git branch -a #列出本地和远程所有分支
git branch -vv #列出本地分支与远程分支的对应关系
与远程分支建立联系
Copy git checkout -b dev_loacal --track origin/dev #新建一个本地dev_loacal分支并与远程dev分支关联
git branch --set-upstream-to dev_loacal origin/dev #将本地分支dev_loacal与远程的dev建立联系
git branch --set-upstream-to=origin/dev dev_loacal #将本地分支dev_loacal与远程的dev建立联系
储存当前状态
Copy git stash #储藏当前状态,切换到其他分支
git stash save stash_1 #储存当前状态,并命名为stash_1
git stash list #查看储藏状态的列表
git stash apply stash_1 #回到原来某个工作状态stash_1,恢复之前的工作状态
git stash drop stash_1 #删除stash_1储藏
git stash pop stash_1 #弹出stash_1,回到原来某个工作状态stash_1,不删除stash_1
git stash branch testchanges #从储藏中创建分支testchanges,检出你储藏工作时的所处的提交,重新应用你的工作,如果成功,将会丢弃储藏
git stash clear # 清空所有储藏
合并: merge/rebase
以上在 dev 分支执行变基,是将dev分支的commit暂存,将 master 分支的commit应用后再将dev分支暂存的commit拿出来应用在dev分支。为了让master分支也获得最新的 commit. 将master分支快进到dev当前commit即可。
合并/merge:
这和 merge 有些不同,merge是将另一个分支新的commit直接放在当前分支的commit之后,rebase是将当前分支的commit暂存,将另一分支的commit应用后再将当前分支暂存的commit拿出来应用在当前分支,因而保持了分支图关系的清晰。
远程
远程分支
Copy git remote show origin #列出远程仓库 origin 的信息
git remote rename origin origin1 #重命名远程仓库为 origin1
git remote rm origin #删除远程仓库origin
远程推送
Copy git push origin dev_local:dev #推送本地分支dev_local到 origin 远程仓库(新建)dev分支
git push --set-upstream origin dev_local:dev #推送并设置本地分支dev_local到 origin 远程仓库(新建)dev分支
git push origin :experimental #删除远程的 experimental 分支
git push origin [name] 创建远程分支(本地分支push到远程)
git branch --set-upstream-to=origin/dev dev_loacal #将本地分支dev_loacal与远程的dev建立联系
Tag
创建一个tag来指向软件开发中的一个关键时期,比如版本号更新的时候可以建一个"v2.0"、"v3.1"之类的标签,这样在以后回顾的时候会比较方便。tag的使用很简单,主要操作有:查看tag、创建tag、验证tag以及共享tag。
Tag 本地操作
查看tag
Copy git tag #查看tag,列出所有tag,按字母排序的,和创建时间没关系
git tag -l 'v1.4.2.*' #查看指定版本的tag
git show v1.4 #显示tag信息
创建tag
Copy git tag v1.0 #创建轻量级tag,这样创建的tag没有附带其他信息
git tag -a v1.0 -m 'first version' #创建轻量级tag:这样创建的tag没有附带其他信息
删除tag
Copy git tag -d v1.0 #删除本地tag
创建一个基于指定tag的分支
Copy git checkout -b tset v0.1.0
Tag 远程操作
创建 tag 后,tag不会上传github服务器, git push
在github网页上看不到tag,需要带 tag 推送
Copy git push origin v1.0 #将v1.0的tag推到服务器
git push origin --tags #将所有tag 一次全部push到github上
删除远程tag
Copy git push origin :refs/tags/v1.0.0 #删除github远端的指定tag
git push origin --delete v1.0.0
重置仓库/丢弃修改
Copy git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态
git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。
git clean -df #返回到某个节点
git clean 参数
-n 显示 将要 删除的 文件 和 目录
-f 删除 文件
-df 删除 文件 和 目录
#恢复到上一次提交前
git checkout . && git clean -xdf
本地仓库重置
Copy git reset --mixed <指定版本HASH> #不删除工作空间改动代码,撤销commit,并且撤销git add . 操作
#这个是默认参数,git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的。
git reset --soft <指定版本HASH> #不删除工作空间改动代码,撤销commit,不撤销git add .
git reset --hard <指定版本HASH> #删除工作空间改动代码,撤销commit,撤销git add . ,恢复到了上一次的commit状态
git reset --soft HEAD^ #撤销commit
git reset --soft HEAD~1 #撤销前1次commit
git reset --soft HEAD~2 #撤销前2次commit
撤销/回滚 revert
单个 commit 撤销
git revert 撤销某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销,作为一次最新的提交。git revert提交一个新的版本,将revert的版本的内容再反向修改回去,版本会递增,不影响之前提交的内容.
Copy git revert HEAD #撤销前一次 commit
git revert HEAD^ #撤销前前一次 commit
git revert commit_id #(比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)
多个 commit 撤销
连续
Copy git revert -n commit_id_start..commit_id_end #提交撤回到commit_id_start的位置
不连续
撤回到commit_id_1和commit_id_3的提交
Copy git revert -n commit_id_1
git revert -n commit_id_3
撤销 merge
由于 merge 是两个分支 多个commit 合并在一个 commit中,因此撤销 merge 需要告诉系统使用哪个 branch
Copy git revert merge_commit_id -m 1
如果不用 -m
参数将会出现错误 is a merge but no -m option was given
这是因为revert的那个commit是一个merge commit,它有两个parent, Git不知道base是选哪个parent,就没法diff,所以你要显示告诉Git用哪一个parent。 一般来说,如果在 master 上 merge dev_branch, 那么parent 1 就是 master ,parent 2 就是 dev_branch
补丁/patch
patch和cherry-pick的功能都是重用commit,功效几乎一样, 但是cherry-pick更为简单.
生成patch文件:
Copy git format-patch <old-commit-sha>...<new-commit-sha> -o <patch-file-dir>
如:
Copy git format-patch 0f500e44965c2e1d3449c05...d37885d260bb228f0a8841d48b -o ~/temp_patch/
生成文件/Users/stone/temp_patch/0001-add-content-to-bb.c.patch 查看 git log
或 git log -p
(有详细的更改内容)
Copy git format-patch commit_id -N #表示生成对应id的commit
git format-patch commit_id #表示从某个id开始所有的commit
git format-patch commit_start...commit_end #表示从start到end
检查patch文件
Copy git apply --stat ~/temp_patch/0001-add-content-to-bb.c.patch
查看是否能应用成功
Copy git apply --check ~/temp_patch/0001-add-content-to-bb.c.patch
应用patch文件
Copy git am -s < ~/temp_patch/0001-add-content-to-bb.c.patch
使用 git apply
一个patch 会直接把对应的changed修改到对应的文件上,需要重新进行一个commit进行添加,这样的操作会导致 patch 的commit丢失。 使用 git am
一个patch 会保留commit。apply中有冲突时对应patch的commit是无法保留的。
cherry-pick/重演commit
基于release-2.0分支新建分支release-2.1, 并且到新创建的分支上
Copy git checkout -b release-2.1 release-2.0
将dev-3.0分支上的某些commit在release-2.1分支上重演
Copy git cherry-pick {dev-3.0分支的某些commit-hash}
如
Copy git cherry-pick
20c2f506d789bb9f041050dc2c1e954fa3fb6910
2633961a16b0dda7b767b9264662223a2874dfa9
5d5929eafd1b03fd4e7b6aa15a6c571fbcb3ceb4
多个commit-hash使用空格分割, commit-hash最好按提交时间先后排列, 即最先提交的commit放在前面.
Git各个状态之间转换指令总结
当对工作区修改(或新增)的文件执行 git add
命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作 git commit
时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 git reset HEAD
命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 git rm --cached <file>
命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 git checkout .
或者 git checkout -- <file>
命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 git checkout HEAD .
或者 git checkout HEAD <file>
命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
Git 示例
1. git 切换远程分支
git clone只能clone远程库的master分支,无法clone所有分支。
Copy git clone http://myrepo.xxx.com/project/.git
cd project
列出所有分支:
remotes/origin/dev
remotes/origin/release
checkout远程的dev分支,在本地起名为dev分支,并切换到本地的dev分支
Copy git checkout -b dev origin/dev #checkout远程的dev分支,在本地起名为dev分支,并切换到本地的dev分支
切换回dev分支开始开发
Copy git checkout dev #切换回dev分支开始开发
将本地dev分支与远程dev分支建立关联
Copy git branch --set-upstream-to=origin/dev dev
git push --set-upstream origin dev_local:dev #本地分支dev_local推送到远程dev分支
新建本地分支,并推送为远程的新分支
Copy git checkout -b dbg_lichen_star
git push origin dbg_lichen_star:dbg_lichen_star
2. 树形展示日志
Copy git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative
3. 彻底删除远程仓库所有文件
Copy git clone git@github.com:ACCOUNT/REPO.wiki.git
cd REPO.wiki
git checkout --orphan empty
git rm --cached -r .
git commit --allow-empty -m 'wiki deleted'
git push origin empty:master --force
4. 如果commit注释写错了,只是想改一下注释,只需要:
gitignore 说明
Copy # 表示此为注释,将被Git忽略
*.a 表示忽略所有 .a 结尾的文件
!lib.a 表示但lib.a除外
/TODO 表示仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ 表示忽略 build/目录下的所有文件,过滤整个build文件夹;
doc/*.txt 表示会忽略doc/notes.txt但不包括 doc/server/arch.txt
bin/: 表示忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
/bin: 表示忽略根目录下的bin文件
/*.c: 表示忽略cat.c,不忽略 build/cat.c
debug/*.obj: 表示忽略debug/io.obj,不忽略 debug/common/io.obj和tools/debug/io.obj
**/foo: 表示忽略/foo,a/foo,a/b/foo等
a/**/b: 表示忽略a/b, a/x/b,a/x/y/b等
!/bin/run.sh 表示不忽略bin目录下的run.sh文件
*.log: 表示忽略所有 .log 文件
config.php: 表示忽略当前路径的 config.php 文件
/mtk/ 表示过滤整个文件夹
*.zip 表示过滤所有.zip文件
/mtk/do.c 表示过滤某个具体文件
FAQ
1. SSH生成id_rsa,id_rsa.pub后,连接服务器却报:Agent admitted failure to sign using the key
错误。
解决:在当前用户下执行命令:
即可解决。
2. 本地文件夹与远程库建立关联
Copy git init .
git remote add origin git@github.com:RunAtWorld/ceph_manual.git #与远程主机关联
git branch --set-upstream-to=origin/master master #建立本地master分支与远程master分支的关联
3. 本地项目上传到git
(1) 进入项目文件夹,通过命令 git init 把这个目录变成git可以管理的仓库
(2) 把文件添加到版本库中
(3) 用命令 git commit告诉Git,把文件提交到仓库。引号内为提交说明
Copy git commit -m 'first commit'
(4) 关联到远程库
Copy git remote add origin 你的远程库地址
如
Copy git remote add origin https://github.com/cade8800/ionic-demo.git
(5) 获取远程库与本地同步合并(如果远程库不为空必须做这一步,否则后面的提交会失败)
Copy git pull --rebase origin master
(6) 把本地库的内容推送到远程,使用 git push命令,实际上是把当前分支master推送到远程。执行此命令后会要求输入用户名、密码,验证通过后即开始上传。
Copy git push -u origin master
4. 上传ssh-key后仍须输入密码
这通常发生使用https方式克隆仓库的时候,解决的方法是使用ssh方式克隆仓库。 如果已经用https方式克隆了仓库,就不必删除仓库重新克隆,只需将 .git/config文件中的
Copy url = https://github.com/Name/project.git
一行改为
Copy url = git@github.com:Name/project.git
参考