- 查看和修改用户名以及邮箱:
git config user.name
git config user.email
- 设置/更改用户名和邮箱,有先后顺序:
git config --global user.name "your name"
git config --global user.email "your email"
-
开启/关闭颜色
git config --global color.ui true
-
换行符操作
Linux是0x0A(LF),win是0x0D0A(CRLF)
AutoCRLF
1、提交时转换为LF,检出时转换为CRLF git config --global core.autocrlf true
2、提交时转换为LF,检出时不转换 git config --global core.autocrlf input
3、提交检出均不转换 git config --global core.autocrlf false
SafeCRLF
1、拒绝提交包含混合换行符的文件 git config --global core.safecrlf true
2、允许提交包含混合换行符的文件 git config --global core.safecrlf false
3、提交包含混合换行符的文件时给出警告 git config --global core.safecrlf warn
- 代理设置
全局代理设置
git config --global http.proxy http://127.0.0.1:1080
git config --global https.proxy https://127.0.0.1:1080
只对github代理设置
git config --global http.https://github.com.proxy https://127.0.0.1:1080
git config --global https.https://github.com.proxy https://127.0.0.1:1080
**注意:**以上两点都是对https协议进行代理设置,也就是仅对git clone https://www.github.com/xxxx/xxxx.git这种命令有效。对于SSH协议,也就是git clone git@github.com:xxxxxx/xxxxxx.git这种,依旧是无效的。
sock5代理设置,只对GitHub进行代理
git config --global http.https://github.com.proxy socks5://127.0.0.1:1089
git config --global https.https://github.com.proxy socks5://127.0.0.1:1089
取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy
查看已有配置
git config --global -l
** 代理文件的位置**
[09:19:05@]$cat ~/.gitconfig
[user]
email = ~@163.com
name = youname
[http "https://github.com"]
proxy = socks5://127.0.0.1:1089
- 初始化一个Git仓库,使用
git init
命令:
git init
Initialized empty Git repository in /Users/michael/learngit/.git/
- 使用命令
git add <file>
,注意,可反复多次使用,添加多个文件,
- git add -A 提交所有变化
- git add -u 提交被修改(modified)和被删除(deleted)文件,不包括新文件(new)
- git add . 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件
git add readme.txt
- 无法将文件夹下的某些文件添加进 Git 进行版本控制
发现原来是子文件夹下面含有 .git 文件夹,因此导致该子文件夹无法被 Git 跟踪,可以通过以下方法解决:
git rm --cached directory
git add directory
注:directory为子文件夹的路径。
- 使用命令
git commit
git commit -s
在vim中添加提交信息(很实用)
git commit -amend
最近提交的commitid中追加提交 (很实用,尤其是往远程仓库提交时,提交上去只有一个commit id ,管理者可以一目了然的看到提交)
git commit -C hard -a --amend
追加到hard,不参数新的提交记录
$ git commit -m "add 3 files."
-m后面输入的是本次提交的说明
git commit -m "提交说明" -a //这是一个偷懒的命令,相当于 git add .; git commit;
git log
命令显示从最近到最远的提交日志,
git log --stat
查看每条log提交对应的修改(比较常用)
git log --graph
命令可以看到分支合并图
git log -p 文件名
可查看该文件以前每一次push的修改内容
git log - p -1 文件名
只查看该文件当前这一次的push内容
git show commit-id filename
只看某次提交中的某个文件变化
git log --grep 关键字
仅显示含指定关键字的提交
git log -S 关键字
仅显示添加或移除了某个关键字的提交
git log --committer zhubo(作者)
仅显示指定提交者相关的提交,没有具体提交内容
git log --author zhubo(作者)
仅显示指定作者相关的提交,有具体提交内容
$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug 20 15:11:49 2013 +0800
可以试试加上--pretty=oneline参数嫌输出信息太多,
$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file
- 命令
git reflog
用来记录你的每一次命令
$ git reflog
ea34578 HEAD@{0}: reset: moving to HEAD^
3628164 HEAD@{1}: commit: append GPL
ea34578 HEAD@{2}: commit: add distributed
cb926e7 HEAD@{3}: commit (initial): wrote a readme file
- Git允许我们在版本的历史之间穿梭,使用命令
git reset --hard commit_id
和git reset --soft commit_id
说明:
--hard
会毁掉提交的暂存区,丢弃改动代码就不要用
--soft
会回到commit_id,对应的提交会保存到暂存区,推荐使用这个
$ git reset --hard HEAD^
HEAD is now at ea34578 add distributed
HEAD^:当前版本的上一版本,上上一个版本就是HEAD^^,
$ git reset --hard 3628164
HEAD is now at 3628164 append GPL
1、用git log可以查看提交历史,以便确定要回退到哪个版本
2、用git reflog查看命令历史,以便确定要回到未来的哪个版本
- 命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区:
- git revert 是生成一个新的提交来撤销某次提交,此次提交之前的commit都会被保留
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
- 用
git status
查看一下状态:
$ git status
\# On branch master# Changes to be committed:
\# (use "git reset HEAD <file>..." to unstage)
\#
\# new file: LICENSE# modified: readme.txt
\#
- 用 git diff HEAD – 命令可以查看工作区和版本库里面最新版本的区别:
Git diff branch1 branch2 --stat //显示出所有有差异的文件列表
Git diff branch1 branch2 文件名(带路径) //显示指定文件的详细差异
Git diff branch1 branch2 //显示出所有有差异的文件的详细差异
git diff -cached 要看已经暂存起来的文件和上次提交时的快照之间的差异
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.
git show
可以看到项目的一些状态
git show commitid
可以查看对应更改- git checkout – file可以丢弃工作区的修改(本地删除,从版本库还原)
$ git checkout -- readme.txt
git checkout branch
就变成了“切换到另一个分支”的命令- 用命令
git rm
要从版本库中删除该文件, 并且git commit
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d17efd8] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
- 查看分支:
git branch
命令查看当前分支, git branch命令会列出所有分支,当前分支前面会标一个*号
查看所有分支git branch -a
包括远程的分支
$ git branch
* dev
master
- 创建分支:
git branch <name>
- 切换分支:
git checkout <name>
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
- 创建+切换分支:
git checkout -b <name>
,命令加上-b
参数表示创建并切换,相当于上面两条命令:
$ git checkout -b dev
Switched to a new branch 'dev'
- 新建分支并切换到远程分支
git checkout -b 本地分支名 origin/远程分支名
- 合并某分支到当前分支:
git merge <name>
, 注意--no-ff
参数 表示禁用Fast forward
$ git merge dev
Updating d17efd8..fec145a
Fast-forward//快捷模式,也就是直接把master指向dev
readme.txt | 1 +
1 file changed, 1 insertion(+)
加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并
$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
git merge --squash dev
将dev分支上的多个commit合并成一个,放在当前分支上,原来的commit历史则没有拿过来,当前修改没问题再做一次commit提交
–squash选项的含义是:本地文件内容与不使用该选项的合并结果相同,但是不提交、不移动HEAD,因此需要一条额外的commit命令。
- 删除分支:
git branch -d <name>
,如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>
强行删除
$ git branch -d dev
Deleted branch dev (was fec145a).
- 当前工作现场“储藏”起来
git stash
$ git stash
Saved working directory and index state WIP on dev: 6224937 add merge
HEAD is now at 6224937 add merge
- 查看储藏:
git stash list
命令
$ git stash list
stash@{0}: WIP on dev: 6224937 add merge
- 恢复储藏现场:
git stash apply
, stash内容并不删除,删除储藏现场:git stash drop
;或git stash pop
恢复的同时把stash内容也删了
$ git stash pop
# On branch dev
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: hello.py
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readme.txt
#
Dropped refs/stash@{0} (f624f8e5f082f2df2bed8a4e09c12fd2943bdd40)
- 在github建立仓库
1、登陆github.com
2、Create New Repository
- github建立仓库后
echo "# my_vimrc" >> README.md
git initgit add README.md
git commit -m "first commit"
//origin 远程仓库的简单名,可以用git remote查看
git remote add origin https://github.com/90geek/my_vimrc.git
git push -u origin master
- 查看远程库的信息,用
git remote
,用git remote -v
显示更详细的信息
$ git remote
origin
$ git remote -v
origin git@github.com:michaelliao/learngit.git (fetch)
origin git@github.com:michaelliao/learngit.git (push)//有上传权才显示
git remote add pb git://github.com/paulboone/ticgit.git 添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用
git remote show [remote-name]
- 本地上传分支,使用
git push origin branch-name
,如果推送失败,先用git pull
抓取远程的新提交
如果您当前分支的上游分支和您当前分支名不匹配,为推送到远程的上游分支,使用git push origin HEAD:LA_NS_Capsule
为推送至远程同名分支,使用git push origin capsule
$ git push origin master
$ git push origin dev
git push origin –tags 如果要一次推送所有(本地新增的)标签上去,可以使用 --tags 选项
强制推送到远程仓库:git push -f
在提交错了,本地回退后提交时会提示落后于远程被拒绝,这个时候就可以用强制提交了
强制更新 git push -u origin +master
-
本地创建和远程分支对应的分支,使用
git checkout -b branch-name origin/branch-name
,本地和远程分支的名称最好一致 -
建立本地分支和远程分支的关联,使用
git branch --set-upstream branch-name origin/branch-name
$ git branch --set-upstream dev origin/dev
Branch dev set up to track remote branch dev from origin.
- 从远程抓取分支,使用git pull,如果有冲突, 在本地合并,解决冲突,再推送
$ git pull
Auto-merging hello.py
CONFLICT (content): Merge conflict in hello.py
Automatic merge failed; fix conflicts and then commit the result.
- 暂存了本地修改
git stash
解决冲突使用
git stash list
可以看到保存的信息,其中stash@{0}
就是刚才保存的标记
git stash pop stash@{0}
还原暂存的内容
有冲突提示`冲突(内容):合并冲突于 文件
vim打开文件,查找如下表示:
<<<<<<< Updated upstream
上游更新内容
=======
本地暂存内容
>>>>>>> Stashed changes
其他命令
git stash save "save message"
: 执行存储时,添加备注,方便查找,只有git stash 也要可以的,但查找时不方便识别。
git stash show
:显示做了哪些改动,默认show第一个存储,如果要显示其他存贮,后面加stash@{KaTeX parse error: Expected 'EOF', got '}' at position 4: num}̲,比如第二个 git stas…num} -p ,比如第二个:git stash show stash@{1} -p
git stash apply
:应用某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,git stash apply stash@{KaTeX parse error: Expected 'EOF', got '}' at position 4: num}̲ , 比如第二个:git st…num} ,比如应用并删除第二个:git stash pop stash@{1}
git stash drop stash@{$num}
:丢弃stash@{$num}存储,从列表中删除这个存储
git stash clear
:删除所有缓存的stash
- 下载的工程带有submodule
当使用git clone下来的工程中带有submodule时,初始的时候,submodule的内容并不会自动下载下来的,此时,只需执行如下> > 命令:git submodule update --init --recursive
- 在当前分支创建标签
git tag <name>
就可以打一个新标签; 用-a
指定标签名,-m
指定说明文字;-s
用私钥签名一个标签
$ git tag v1.0
$ git tag -a v0.1 -m "version 0.1 released" 3628164
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a
- 查看所有标签
git tag
$ git
tagv1.0
- 查看标签信息
git show <tagname>
$ git show v0.9commit 622493706ab447b6bb37e4e2a2f276a20fed2ab4
Author: Michael Liao <askxuefeng@gmail.com>
Date: Thu Aug 22 11:22:08 2013 +0800
add merge
...
- 推送一个本地标签
git push origin <tagname>
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
- 推送全部未推送过的本地标签
git push origin --tags
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 554 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v0.2 -> v0.2
* [new tag] v0.9 -> v0.9
- 删除一个本地标签
git tag -d <tagname>
$ git tag -d v0.9
Deleted tag 'v0.9' (was 6224937)
- 删除一个远程标签
git push origin :refs/tags/<tagname>
$ git push origin :refs/tags/v0.9
To git@github.com:michaelliao/learngit.git
- [deleted] v0.9
patch
- 什么是patch?简单来讲,patch中存储的是你对代码的修改
- 什么是生成patch?生成patch就是记录你对代码的修改并将其保存在patch文件中
- 什么是打patch?打patch就是将patch文件中对代码的修改,应用到源代码,从而把对代码的修改应用到code中;
生成patch
命令:git format-patch
git format-patch -1 <r1>
#生成单个commit的patch
git format-patch HEAD^
#生成最近的1次commit的patch
git format-patch HEAD^^
#生成最近的2次commit的patch
git format-patch HEAD^^^
#生成最近的3次commit的patch
git format-patch HEAD^^^^
#生成最近的4次commit的patch
git format-patch -M master
与分支比较生成patch,-M选项表示这个patch要和那个分支比对
git format-patch <r1>..<r2> #生成两个commit间的修改的patch(包含两个commit. <r1>和<r2>都是具体的commit号)
git format-patch <r1> #生成某commit以来的修改patch(不包含该commit)
git format-patch --root <r1> #生成从根到r1提交的所有patch
打patch
命令:git am
git apply --stat 0001-limit-log-function.patch # 查看patch的情况
git apply --check 0001-limit-log-function.patch # 检查patch是否能够打上,如果没有任何输出,则说明无冲突,可以打上
(注:git apply是另外一种打patch的命令,其与git am的区别是,git apply并不会将commit message等打上去,打完patch后需要重新git add和git commit,而git am会直接将patch的所有信息打上去,而且不用重新git add和git commit,author也是patch的author而不是打patch的人)
git am 0001-limit-log-function.patch # 将名字为0001-limit-log-function.patch的patch打上
git am --signoff 0001-limit-log-function.patch # 添加-s或者--signoff,还可以把自己的名字添加为signed off by信息,作用是注明打patch的人是谁,因为有时打patch的人并不是patch的作者
git am ~/patch-set/*.patch # 将路径~/patch-set/*.patch 按照先后顺序打上
git am --abort # 当git am失败时,用以将已经在am过程中打上的patch废弃掉(比如有三个patch,打到第三个patch时有冲突,那么这条命令会把打上的前两个patch丢弃掉,返回没有打patch的状态)
git am --resolved #当git am失败,解决完冲突后,这条命令会接着打patch
冲突解决
- 如果不想打这一系列patch了,直接:
git am --abort
。 - 如果还想打:
(1) 根据git am失败的信息,找到发生冲突的具体patch文件,然后用命令git apply --reject <patch_name>,强行打这个patch,发生冲突的部分会保存为.rej文件(例如发生冲突的文件是a.txt,那么运行完这个命令后,发生conflict的部分会保存为a.txt.rej),未发生冲突的部分会成功打上patch
(2) 根据.rej文件,通过编辑该patch文件的方式解决冲突。
(3) 废弃上一条am命令已经打了的patch:git am --abort
(4) 重新打patch:git am ~/patch-set/*.patchpatch
####附录:
#####附录三:
实际提交gerrit,没有pull,提交上去反应冲突,需要解决
git reset --soft HEAD^2
切回提交之前,要提交的会在暂存区(操作之前代码备份一份,以防万一)
git log
查看是否切回
git pull
同步gerrit 仓库代码
git status
查看暂存区的提交是否正常
git commit -s
正常后再次提交,这个是最终要提交的commit id
git log -stat
查看提交文件是否正确
git add Platform.c
发现有个文件有多余的提交,修改后添加
git commit --amend
追加提交到刚才的commit id上
git push
将提交推到远程的gerrit仓库
#####附录四:
git pull 冲突,也可以用于所有冲突解决
git stash
暂存本地修改
stash list
查看暂存列表
git reset --hard 2b14d62
切回修改之前的分支
git pull
更新
git stash pop stash@{0}
还原暂存内容
提示冲突如下,进行解决
13:51:29-@code-server.gen $ git stash pop stash@{0}
自动合并 Library/Ls7a1000Lib/Ls7aInitLib/Ls7a.c
自动合并 Include/Library/Ls7aInitLib.h
冲突(内容):合并冲突于 Include/Library/Ls7aInitLib.h
13:51:48-@code-server.gen $ vim Include/Library/Ls7aInitLib.h
/<<<<<<< Updated upstream
#define LS7A_MISC_BASE (HT1_MEM_BASE_ADDR | MISC_BASE_ADDR)
#define LS7A_ACPI_BASE (LS7A_MISC_BASE | LS7A_ACPI_OFFSET)
#define LS7A_RTC_REG_BASE (LS7A_MISC_BASE + LS7A_RTC_REG_OFFSE)
/=======
#define LS132ENA_BASE 0x900000001fe00000
#define LS132ENA_DYNAMIC_FREQ 0x0008
#define LS132ENA_RESET 0x420
#define LS7A_MISC_BASE (HT1_MEM_BASE_ADDR | MISC_BASE_ADDR)
#define LS7A_ACPI_BASE (LS7A_MISC_BASE | LS7A_ACPI_OFFSET)
/>>>>>>> Stashed changes
附录五:
GIt 追加上一次提交(保持Change-Id不变即可)
比如发现test.txt 文件忘记修改了
step1. vim test.txt
修改
step2. git add test.txt
step3.git commit --amend
把文件和上次提交合并(追加提交)
说明:
--amend
可以保持change_Id和上次一样,如果change-id被删掉的话,这条命令会生成新的chang_id,此时如果想合并到上次的修改中,必须复制上次的Change_Id作为本次的Change_id
step4.git push origin HEAD:refs/for/$branch
Gerrit中的一个Change就是一个Review任务,它对应一个commit。 每个commit,应该是为了一个目的的完整修改。如果某一次修改不完全,就需要修正该commit。
每一次修正之前的commit,重新提交时,都应该保持Change-Id不变,这样就不会产生新的Change,而是在原有的Change下产生一个新的Patch Set。
所有的Patch Set中,只有最新的一个是真正有用的,能够合并的。
用 --amend 选项,这种方式可以比较方便的保持原有的Change-Id,推荐使用。
附录六:
10:57:29-@code-server.gen $ git push origin HEAD:refs/for/dev%r=mail1@.cn,r=mail2@.cn
Counting objects: 38, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (16/16), 2.40 KiB | 0 bytes/s, done.
Total 16 (delta 10), reused 0 (delta 0)
remote: Resolving deltas: 100% (10/10)
remote: Processing changes: refs: 1, done
To ssh://zhubo@rd.loongson.cn:29418/vUDK2018-loongson
! [remote rejected] HEAD -> refs/for/gen-dev%r=mail1@.cn,r=mail2@.cn (you are not allowed to upload merges)
error: 无法推送一些引用到 'ssh://@rd..cn:29418/master'
是由于已经有人提交了这个补丁,我进行了pull ,但补丁又被Abandoned了 ,所以打不上去。
方法一:笨办法
先将你的提交回退到上一版git reset --soft commitid
本地做保存git stash
回退到Abandned补丁之前的版本 git reset --hard commitid
恢复本地保存:git stash pop stash @{0}
进行本地爱add
commit -s
推到远程仓库 git push origin HEAD:refs/for/dev
方法二:
现在去打开这个补丁提交的greeit restore回来就可以了 ,网上的方式,还没实现
附录七:
不修改代码只修改log
1、如果是最近提交的log
在最近提交进行追加提交git commmit --amend
查看是否修改:git log
强制推送到远程仓库:git push -f
2、修改历史log
查看log,确定修改哪条log,复制比它还老的commit id git log
列出commitid之前的log ,如下 git rebase -i commitid
pick e76cb12 更新了grep搜索的包含文件类型
pick d016f28 csc 显示目录深度改成了5
pick 33dead5 填加了tab的切换标志 commit --amend
# Rebase 57e3145..33dead5 onto 57e3145
……
将第一个pick
修改为edit
, 然后:wq
退出,会显示如下信息,如果要改日志,执行git commit --amend,如果修改完成后,执行git rebase --continue
Stopped at d016f28... csc 显示目录深度改成了5
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
修改日志git commit --amend
修改完成 git rebase --continue
打印信息
18:02:51-@code-server.gen vim-init $ git commit --amend
[分离头指针 d4d659e] csc 显示目录深度改成了5 git rebase -i commitid Signed-off-by: user <user@.cn>
1 file changed, 1 insertion(+), 1 deletion(-)
18:04:00-@code-server.gen vim-init $ git rebase --continue
Successfully rebased and updated refs/heads/master.
查看是否修改:git log
强制推送到远程仓库:git push -f
附录八:
回退提交后的某个文件,不是最近一次提交,是之前的某个commitid
1、获取想要回退到的版本的commit id(假设为2fe1167)
2、git 回退版本git reset 2fe1167 test.txt
3、回退之后查看当前状态 会发现没有如想象中的回退到那个版本
4、回退后会到暂存区,确认没有问题后在进行提交就好了
附录九:
多次commit log 合并成一个;
使用git merge
通过分支之间的合并用参数--squash
将原有分支的上的多次commit 合并过来做一次commit
git checkout another
git merge --squash another
git commit -m "message here"
--squash
含义和原理如下:
–squash选项的含义是:本地文件内容与不使用该选项的合并结果相同,但是不提交、不移动HEAD,因此需要一条额外的commit命令。其效果相当于将another分支上的多个commit合并成一个,放在当前分支上,原来的commit历史则没有拿过来。