git 备忘录
- 0. 本文目的
- 1. git使用GUI比较程序
- 2. git中文件的几种状态
- git diff和git diff --cached
- git difftool和git mergetool
- 查看版本差异/版本回退/撤销回退
- 3. 单个文件撤销工作区修改
- 4. 查看远端(remote)地址
- 5. 删除untracked状态的文件、目录
- 6. 从本地文件系统的仓库中clone
- 7. 设置git命令别名(alias)
- 8. git checkout xxx后,git log显示不全?
- 9. git打标签(tag)
- 10. git reset和git co的区别?
- 11. git撤销修改
- 12. 从内网机器克隆代码
- 13. tag操作
- 14. 忽略文件权限(mode)的差异
- 在commit中查找
- 15. 规范书写git commit
- 16. git clone使用https协议还是ssh协议,或者git协议?
- 17. 管理ssh key
- 18. 存储密码
- 19. 使用git rebase
- 20. 使用rebase和merge的场景
- 21. git实践
- 22. 修改先前的本地commit的author
- 23.
COMMIT_EDITMSG
文件出现问题 - 24. git操作中出现Unlink of file '......' failed. Should I try again?
- 25. git遭遇文件名过长
- 26. git reset --hard后恢复暂存区文件
- 26. git reset三种模式(--hard --soft --mixed)的含义、差别
- 27. 查看最近一次commit修改了哪些文件?
- 28. 恢复删除的branch
- 29. 已经add过的文件,可以ignore吗?
- 30. git clone后打开文件显示乱码
- 31. git add仅添加已追踪的文件
- 32. 使用git rebase的一个典型场景
- 33. git使用socks代理加速
- 34. 用gitolite搭建git服务器
- 35. git获取所有分支(fetch all branches)
- 36. git clone pytorch或caffe速度慢
- 37. 可以只fetch某一次commit吗
- 38. 创建orphan分支
- 39. 显示本地分支和远程分支的跟踪关系
- 40. git 用--depth=1克隆后用git拉取更新
- 41. git merge冲突时,用自己的或别人的代码
- 42. git stash 贮藏的使用
0. 本文目的
公司里用svn管理代码,但在个人开发机上管理代码用git更方便,因为:1)本地就可以执行commit/checkout,不需要连到服务器;2)我的代码修改版本太多,主要给自己看。
主要是在Git Bash中敲基本的git命令,辅助一些GUI工具,因为:1)Git Bash能正确显示中文,cmd不能; 2)比较目录等情况下,GUI软件效率高。
1. git使用GUI比较程序
一个典型的问题是:如何比较两次git commit / 两个branch 下的整个repo?
配置
-
需要安装比较工具,我用的是Beyond Compare4。在没有使用git的时候,Beyond Compare的易用性也让我在不同版本代码的比较和合并中颇有收益。
-
还需要在git中配置Beyond Compare
Beyond Compare 4注册码:
w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwfXv5n0IHDp5hv
1BM3+H1XygMtiE0-JBgacjE9tz33sIh542EmsGs1yg638UxVfmWqNLqu-
Zw91XxNEiZF7DC7-iV1XbSfsgxI8Tvqr-ZMTxlGCJU+2YLveAc-YXs8ci
RTtssts7leEbJ979H5v+G0sw-FwP9bjvE4GCJ8oj+jtlp7wFmpVdzovEh
v5Vg3dMqhqTiQHKfmHjYbb0o5OUxq0jOWxg5NKim9dhCVF+avO6mDeRNc
OYpl7BatIcd6tsiwdhHKRnyGshyVEjSgRCRY11IgyvdRPnbW8UOVULuTE
- Beyond Compare提示到期
如果Beyond Compare提示评估到期,卸载、删注册表、重装后,还是提示评估到期,那么:
修改C:\Program Files\Beyond Compare 4\BCUnrar.dll ,这个文件重命名或者直接删除
在Git Bash中编辑~/.gitconfig
,确保有如下字段:
[diff]
tool = bc4
[difftool "bc4"]
cmd = "\"D:\\soft\\Beyond Compare 4\\BCompare.exe\" \"$LOCAL\" \"$REMOTE\""
[merge]
tool = bc4
[mergetool "bc4"]
cmd = "\"D:\\soft\\Beyond Compare 4\\BCompare.exe\" \"$LOCAL\" \"$REMOTE\""
注意其中Beyond Compare的路径写法,反斜杠、引号都不能少;并且应该使用cmd而不是path
使用
比较两次commit:
git difftool commit_id1 commit_id2 -d
其中-d
表示以目录形式比较,而不是默认的“逐文件比较”。
比较两个分支,例如master和develop分支:
git difftool origin/master origin/develop -d
2. git中文件的几种状态
在执行git add后,在修改文件后,在git commit后,使用git status查看状态,感觉有点晕,于是仔细研究下git的状态:
针对单个文件,可以粗略分成2个大的状态:
- untracked,也就是没有被git跟踪,只要文件存在,并且没有被git add过,就是untracked状态
- tracked,被git跟踪,只要被git add过(并且没有被git remove过),就是tracked状态。它可以进一步细分:
- unmodified,没有修改,是一个文件指被git add和git commit过,而当前working area中的该文件与commit时一致
- (not staged) modified,命令行下显示为红色,是指文件被git commit过,并且现在在工作区被修改了,但是没有通过git add放到staging area(暂存区)
- modified,命令行下显示为绿色,是指文件有被git commit过,现在在工作区被修改了,并且也被git add了,但是没有被git commit过
- new file,命令行下显示为绿色,是指文件第一次被git add(而处于staging area),而没有被git commit
相应的,对于整个工程的文件,有3个区域:
git diff和git diff --cached
输入git diff
,查看到的是工作区和暂存区的不同
输入git diff --cached
,查看到的是暂存区和HEAD的不同。
如下测试可以验证:
mkdir -p /tmp/git-demo
cd /tmp/git-demo
git init .
echo "#include <stdio.h>" >> main.c
echo "this is the readme" >> readme.md
git add .
git commit -m "first commit"
echo "int main(){printf("hello\n"); return 0;}" >> main.c
echo "add a new line" >> readme.md
git add main.c
git diff
git diff --cached
也即:首先把main.c和readme.md执行git add和git commit;然后分别修改main.c和readme.md,但是只git add main.c;这时候git diff
只能看到readme.md的不同,是working area和stage的比较;此时输入git diff --cached
只能看到main.c的不同,是stage和HEAD的比较。
git difftool和git mergetool
但凡用到git diff
的地方,包括git diff
本身,以及带的其他参数例如git diff --cached
,都可以把diff
换成difftool
,这样的话就会使用在~/.gitconfig中配置的diff的图形界面工具来执行比较。e.g.:
git difftool -y
git difftool --cached -y
其中-y
表示yes,不要询问我是否用我配置的GUI工具(例如beyond compare)来打开,直接打开就是了。
类似的,git merge
也有对应的git mergetool
,只要先前在~/.gitconfig中配置过mergetool即可。实际上,beyond compare也可以做mergetool,我的difftool和mergetool都是它。
查看版本差异/版本回退/撤销回退
这里考虑的是整个工程的所有代码文件。
例如有3次commit,现在(在commit_id3的基础上,有代码修改!)突然发现代码有bug,而第二次的commit当时测试是没有bug的,那么我最新一次(第三次)commit中肯定是写了bug的,就希望从这次commit中新增的代码中找出来。
此时,如果要回退版本,因为working area有代码没有commit,应当add并commit,否则reset后回不来
此时有三种选择:
- 查看两个版本之间的差异:
git difftool -y commit_id2 commit_id3
- 把working area,(从commit_id3)切换回
commit_id2
,并且保证以后能再切换回commit_id3
git reset --hard commit_id2
- 从
commit_id2
切换回commit_id3
:
先使用git reflog
查看得到commit_id2
的值,然后git reset --hard commit_id3
3. 单个文件撤销工作区修改
git checkout -- filename
4. 查看远端(remote)地址
有时候在同一目录下,git clone了好几份类似的代码,为了区分它们,可以把它们的下载地址放在一个readme.txt中,但是仍然不方便。
简单方便的方法是:进入各自repo的目录,查看remote:
cd hed
git remote origin show
其中origin是默认的远端名字,就像master是默认的分支一样。结果如下:
⚡ git remote show origin
* remote origin
Fetch URL: https://github.com/zeakey/hed
Push URL: https://github.com/zeakey/hed
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
5. 删除untracked状态的文件、目录
- 删除单个untracked状态的文件
git clean -f xxx
其中-f
表示force,强制删除。因为git的配置中clean.requireForce
默认为true,所以必须加-f
才能正常执行清除(个人猜测:用来防止小白误删文件)
- 删除所有untracked状态的文件
git clean -f
- 删除所有untracked状态的文件、目录
git clean -df
6. 从本地文件系统的仓库中clone
情景:项目中用到一个开源项目(比如opencv),它的代码仓库比较大,而又需要经常使用它的不同分支,那么最好把它各个分支都checkout出来。每个branch都从github上clone下来,会非常慢,也没有必要。
首先要明确下,git clone
可以指定-b branch_name
来克隆指定的branch,而如果不指定的话其实也只是克隆一个分支,只不过是HEAD
对应的分支,最常见的情况下是master分支。
其次明确下,git clone
可以从本地文件系统进行:
git clone file:///path/to/local/machine/repo
#或者:
git clone /path/to/local/machine/repo
因此需要注意,从本地文件系统的repo进行git clone,只能指定本地文件系统repo中的本地分支。
完整步骤举例:
cd ~/work
git clone https://github.com/opencv/opencv
# 查看下有哪些分支
git branch -a
# 把所有的远程分支,都在本地创建同名分支
# 参考:
git branch -r | grep -v '\->' | grep -v `git branch | awk '/\*/ { print $2; }'`| while read remote; do git branch --track "${remote#origin/}" "$remote"; done
# 切换到其他工作目录,从本地文件系统的repo clone,速度飞起
cd ~/work/
git clone ~/work/opencv opencv_2.49 -b 2.4
7. 设置git命令别名(alias)
~/.gitconfig
添加:
[alias]
co = checkout
ci = commit
st = status
br = branch
hist = log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short
type = cat-file -t
dump = cat-file -p
8. git checkout xxx后,git log显示不全?
需要加上branch的名字。e.g.:
git log master
或
git hist master
9. git打标签(tag)
tag和branch的区别: branch是一系列的commit,tag则是一个commit。
通常是对历史版本中某个commit打标签,步骤:
git hist #查看提交情况,用来获取commit id
git co xxxxx # 切换到某个commit
git tag tag_name #打标签,名字是tag_name
10. git reset和git co的区别?
不太懂,挖坑代填。
11. git撤销修改
分好几种情况
1. 撤销工作区修改
git checkout file_name #检出某个文件
或
git checkout . #整个目录都从新检出
2. 撤销暂存区修改
git reset file_name
3. 撤销提交
git revert HEAD
其实我对git revert还不怎熟悉
12. 从内网机器克隆代码
从内网linux主机克隆到本地windows机器,使用ssh协议
git clone ssh://zz@172.xx.xx.xx:/home/zz/work/cnn-infer-testbed
从内网Windows主机克隆代码
万能的方法是,在windows主机上临时开启git daemon,类似于python开启http server
git daemon --base-path=<path_to_folder_containing_project_folder> --export-all
然后在本地机器(client)上克隆:
git clone git://<local ip>/<project name>
ref: How to git clone a repo in windows from other pc within the LAN?
注意:如果是从Windows主机clone到Linux上,在Linux上修改并commit后,无法git push回到Windows,见git server hosting using git:// protocol, unable to set SO_KEEPALIVE, no such file or directory。解决方案:在Windows上的repo中添加remote为Linux上的repo地址,e.g:
git remote add linux-machine ssh://zz@172.xx.xx.xx:/home/zz/work/yyy
git pull linux-machine master
13. tag操作
给当前commit添加tag:
git tag my_tag_name
给已有tag改名字:(则对应的commit此时有两个tag)
git tag new old
删除已有tag:
git tag -d tag_name
给远程的tag改名字,步骤:
git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags
添加tag,比较好的做法
git tag -a 1.6.0.4011 -m "hi3559"
查看tag及message
git tag -l -n
14. 忽略文件权限(mode)的差异
比如我在Linux上git clone的代码,随后整个仓库拷贝到Window上,git st看到很多文件被改了,但是我实际上没有改,原因是文件的mode在复制的时候被改变了:
$ git diff tools/script/test_android.sh
diff --git a/tools/script/test_android.sh b/tools/script/test_android.sh
old mode 100755
new mode 100644
解决办法也很简单:忽略mode的差异
git config --global --add core.filemode false
在commit中查找
git hist --grep="feature"
既然是用grep,自然想到grep -i,invert模式,找到“非xxx”的内容:
git hist --grep="feature" --invert-grep
15. 规范书写git commit
规范的commit,排查问题方便,看起来也没管,是正规军的模样,例如:https://github.com/junluan/shadow/commits/master
每次git commit时,注释中有提示信息。通过设定git的commit.template来增加提示信息(而不是修改):
- 修改
~/.gitconfig
,添加:
[commit]
template = ~/.gitmessage
- 新建
~/.gitmessage
,内容:
# <type>: (If applied, this commit will...) <subject> (Max 50 char)
# |<---- Using a Maximum Of 50 Characters ---->|
# Explain why this change is being made
# |<---- Try To Limit Each Line to a Maximum Of 72 Characters ---->|
# Provide links or keys to any relevant tickets, articles or other resources
# Example: Github issue #23
# --- COMMIT END ---
# Type can be
# feat (new feature)
# fix (bug fix)
# refactor (refactoring production code)
# style (formatting, missing semi colons, etc; no code change)
# docs (changes to documentation)
# test (adding or refactoring tests; no production code change)
# chore (updating cmake scripts etc; no production code change)
# --------------------
# Remember to
# Capitalize the subject line
# Use the imperative mood in the subject line
# Do not end the subject line with a period
# Separate subject from body with a blank line
# Use the body to explain what and why vs. how
# Can use multiple lines with "-" for bullet points in body
# --------------------
# For more information about this template, check out
# https://gist.github.com/adeekshith/cd4c95a064977cdc6c50
ref: 优雅的提交你的 Git Commit Message
16. git clone使用https协议还是ssh协议,或者git协议?
参考 学习 git clone 几种不同的协议,简而言之:
-
git clone https://gitlab.com/xxx/yyy
适合:初学者,或者克隆的是开源公共项目 -
git@gitlab.com:xxx/yyy.git
适合:项目maintainer,项目管理员,通常搭配ssh key,先生成和粘贴ssh公钥到gitlab上,第一次clone输入凭据,以后免密码
其他的暂时不打算用。
17. 管理ssh key
管理多个ssh key
例如,同时需要使用github, 公司gitlab服务器,gitee
每个平台上最好分别设定ssh key,方便管理。
参照这篇:GitLab配置ssh key,直接照着做好了,就先不粘贴整理了。
粘贴ssh key遇到错误:Fingerprint 已经被使用 Fingerprint cannot be generated
通常是用xshell、git-bash、scure-crt等终端连接到远程服务器时,cat查看ssh公钥内容时候有多余的换行,拷贝到gitlab的网页上后无法被正确识别。
其实可以看出来的,正常的key是会自动帮你填写一个key的名字的,有多余空行的话就不自动生成key的名字。
解决办法就是从samba打开公钥文件然后拷贝粘贴。
18. 存储密码
有时候代码仓库是用https协议的,没法改成ssh协议,每次输入密码很烦。设置记住密码即可:
git config --localcredential.helper store
如果要全局设定,则改用global参数:
git config --global credential.helper store
19. 使用git rebase
git rebase的作用,是把当前分支的commit都临时取消掉,然后当前分支更新到指定分支的最新commit,在这个“最新”commit上,把本分支刚刚弄成patch的commit给“贴回去”,如果有冲突则需要手动解决一下。
好处:相比较merge操作而言,避免了一次不必要的commit记录。
让当前分支变基(rebase)为origin远端的master分支:
git rebase origin/master
20. 使用rebase和merge的场景
下游分支(featrue1)更新上游分支(master)内容的时候用rebase
上游分支合并下游分支内容的时候使用merge
ref: Git16 Rebase
个人的见解是:
如果要合并两个分支的代码,如果没有冲突,用哪个都可以,需要考虑的仅仅是“多引入一个commit是否有必要”;
如果要合并的两个分支的代码,有冲突,或者说有可能有冲突,那么根据冲突的优势劣势方来确定:
- 如果被合并进来的分支,在冲突的代码中占主导优势,那么当前branch应当是作出让步的一方。用git rebase。
- 如果被合并进来的分支,处于劣势,一旦有冲突会优先改掉、干掉被合并进来的这个分支的代码,那么应该用git merge
21. git实践
- 利用orphan分支,在同一个repo中并行管理两个项目的代码
- 两个本地repo共用一个remote,独立开发和管理:基于branch和remote branch,以及git push默认分支的设定
- 利用git rebase和git squash,在git push到remote前压缩commit节点(参考:https://www.cnblogs.com/dsxniubility/p/4460834.html)
22. 修改先前的本地commit的author
首先
git config --global user.name "xxx"
git config --global user.email "xxx@yyy.com"
然后:
git commit --amend --reset-author
23. COMMIT_EDITMSG
文件出现问题
在git commit --amend
时提示:
.git/COMMIT_EDITMSG" E513: 写入错误,转换失败 (请将 'fenc' 置空以强制执行
解决办法:删除.git/COMMIT_EDITMSG
文件。然后退出现有git commit的vim窗口,重新git commit --amend即可。
24. git操作中出现Unlink of file '......' failed. Should I try again?
在操作git中有时候会提示 Unlink of file '......' failed. Should I try again?
原因是你工作目录有某些文件正在被程序使用,这个程序多半是Idea,VS或者eclipse,当然也可能是其他程序
解决方案不是简单的选择y或者n,而是关闭IDE,让IDE把这些文件释放掉
ref: https://www.cnblogs.com/wormday/p/git_unlink_of_file_failed_should_i_try_again.html
25. git遭遇文件名过长
error: unable to create file xxx Filename too long
出现在Windows下,git repo中的文件名绝对路径过长,创建失败。
解决办法:
git config --global core.longpaths true
26. git reset --hard后恢复暂存区文件
执行git reset --hard
后,暂存区(先前执行过git add但是没commit)的文件变化就找不到了。实际上可以找到,不过比较hack,也不适合修改的文件很多的情况。
find .git/objects/ -type f | xargs.exe ls -lt | sed 5q
,此命令找到最近5次git add的文件的内容;
git cat-file -p hash_value
查看对应哈希值的文件内容到屏幕上,可以配合重定向符号写入到文件。
https://blog.csdn.net/yeluosc/article/details/76690678
26. git reset三种模式(--hard --soft --mixed)的含义、差别
通用命令格式:
git reset --<reset_mode> commit_id
其中reset_mode
有--hard
, --soft
和--mixed
三种取值,--mixed
是默认值;
commit_id
是提交记录中的某一个哈希值,也可以是HEAD
,HEAD^1
这样的表达式。
git reset的三种模式,共同点是把本地仓库(repo)的HEAD切换到commit_id
,不同点是“工作区、暂存区是否也跟着改变到commit_id
中文件对应状态:
git reset --hard
: 工作区、暂存区、本地仓库,都被切换到commit_id状态git reset (--mixed)
: 暂存区、本地仓库被修改到commit_id状态,工作区不变git reset --soft
:只有本地仓库被切换到commit_id状态,工作区、暂存区都不变
27. 查看最近一次commit修改了哪些文件?
git log -1 --stat
28. 恢复删除的branch
Git会自行负责分支的管理,所以当我们删除一个分支时,Git只是删除了指向相关提交的指针,但该提交对象依然会留在版本库中。
因此,如果我们知道删除分支时的散列值,就可以将某个删除的分支恢复过来。在已知提交的散列值的情况下恢复某个分支:
git branch <branch_name> <hash_val>
如果我们不知道想要恢复的分支的散列值,可以用reflog命令将它找出来。如:
ref: Git删除分支/恢复分支
29. 已经add过的文件,可以ignore吗?
如果仅仅是add了,但是没有commit过,相对容易做到。
原理:从暂存区取消记录文件/文件夹。
也就是:
git rm --cached file.txt # 取消track单个文件
git rm --cached imgs -r # 取消track单个文件夹
30. git clone后打开文件显示乱码
通常是如下几个条件共同产生的:
- 在Windows下编写的代码
- 代码里有中文
- 代码文件格式不是UTF-8
解决:批量转换为UTF-8编码:
find . -name '*.cpp' -exec enca -L zh_CN -x UTF-8 {} \;
find . -name '*.h' -exec enca -L zh_CN -x UTF-8 {} \;
31. git add仅添加已追踪的文件
git add -u
即可
在git中有好多的指令,但是今天这几个指令就很容易忘记而且还容易混淆
git add -u
<==> git add –update
提交所有被删除和修改的文件到数据暂存区
git add .
提交所有修改的和新建的数据暂存区
git add -A
<==> git add –all
提交所有被删除、被替换、被修改和新增的文件到数据暂存区
来源:https://blog.csdn.net/dayewandou/article/details/78513578
32. 使用git rebase的一个典型场景
git checkout -b dev
echo "hello" >> info.txt
git add .
git commit -m "add sth"
git checkout master
git merge dev
33. git使用socks代理加速
开启ss后查看端口,例如我是1080,则:
git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'
然后就能高速使用git下载源码了。
34. 用gitolite搭建git服务器
2015-08-21 23:33
心血来潮的先在本地的fedora-server上装配了起来。
用gitolite搭建git服务器,作为代码版本控制server。gitolite比较流行,官方文档齐全。
fedora22下配置gitolite
一台server:我使用fedora22-server
依赖项:perl-devel, git-core, openssh
可能遇到的问题:
Can't locate Time/HiRes.pm in @INC (@INC contains: /home/git/gitolite/src/lib /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5 .) at /home/git/gitolite/src/lib/Gitolite/Common.pm line 76.
需要安装perl-devel:
sudo dnf install perl-devel
ssh公钥的设定
workstation上的gitolite设定好了,给用户使用的时候,用户每次都输入密码不方便,一个策略是使用ssh-key。通过在客户端上生成rsa的公钥,上传到gitolite-admin这个repo的keydir中,并以用户名.pub
形式命名,然后在此repo的conf目录中的配置文件中对指定repo进行读写权限的设定。
具体设定的语法规则,可以去查看gitolite的manual。
值得注意的一点是:在添加rsa的公钥文件后,请git add keydir
,否则这个文件没有被track,在配置文件中的配置也就不会生效。
CentOS7下gitolite3的配置
# 先确保添加了epel的repo
yum install gitolite3
按照/usr/share/doc/gitolite-3/
下的readme文档进行配置,出了点问题:配置到各种git config --global后,要git clone gitolite-admin了,一直提示没有权限。ssh-key也添加了。google一番发现:ref
[root@dlp ~]# su - gitolite3
-sh-4.2$ ssh-keygen -f ~/.ssh/gitadmin
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): # set passphrase
Enter same passphrase again: # confirm
Your identification has been saved in /var/lib/gitolite3/.ssh/gitadmin.
Your public key has been saved in /var/lib/gitolite3/.ssh/gitadmin.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx gitolite3@dlp.server.world
The key's randomart image is:
-sh-4.2$ gitolite setup -pk ~/.ssh/gitadmin.pub
Initialized empty Git repository in /var/lib/gitolite3/repositories/gitolite-admin.git/
Initialized empty Git repository in /var/lib/gitolite3/repositories/testing.git/
-sh-4.2$ vi ~/.ssh/config
# create new
# any name you like
host GitServer
user gitolite3
# Git server's hostname or IP address
hostname 10.0.0.30
port 22
# secret key
identityfile ~/.ssh/gitadmin
-sh-4.2$ chmod 600 ~/.ssh/config
-sh-4.2$ git config --global user.name "gitolite3"
-sh-4.2$ git config --global user.email "gitolite3@server.world"
-sh-4.2$ git config --global push.default simple
# clone admin repository to finish setup
-sh-4.2$ git clone ssh://GitServer/gitolite-admin
Cloning into 'gitolite-admin'...
The authenticity of host '10.0.0.30 (10.0.0.30)' can't be established.
ECDSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.30' (ECDSA) to the list of known hosts.
Enter passphrase for key '/var/lib/gitolite3/.ssh/gitadmin':
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (6/6), done.
35. git获取所有分支(fetch all branches)
在StackOverFlow上的问答:
可能会遇到提示:'fatal: A branch named 'origin/master' already exists.'
解决办法:用如下命令:
git branch -r | grep -v '\->' | grep -v `git branch | awk '/\*/ { print $2; }'`| while read remote; do git branch --track "${remote#origin/}" "$remote"; done
36. git clone pytorch或caffe速度慢
可以从gitee导入github repo,而pytorch的话,submodule比较多,也要导入。
我在gitee的两个账号 aczz 和 arczz,里面有很多submodule,可以考虑试试。不过可能比较旧了。
37. 可以只fetch某一次commit吗
场景:希望学习某个repo是如果写出来的,则新建一个本地空repo(git init),添加remote后fetch,再cherry-pick即可。
举例:
mkdir dev-easycnn
cd dev-easycnn
git init
git remote add origin https://gitee.com/aczz/EasyCNN
git fetch origin
git cherry-pick bf22931
38. 创建orphan分支
在一个已有commit的repo中创建orphan分支。
cd repo
git checkout --orphan dev
git rm -rf .
39. 显示本地分支和远程分支的跟踪关系
git branch -vv
40. git 用--depth=1克隆后用git拉取更新
git pull --unshallow
或者
git fetch --unshallow
41. git merge冲突时,用自己的或别人的代码
假设冲突的文件叫做 word.txt
,则:
git checkout --ours word.txt # 使用我们的代码,也就是merge前的
git checkout --theirs word.txt # 使用“他们”的代码,也就是对面来的
此外还需要注意,git rebase阶段如果冲突,则ours和theirs的定义,和git merge时的定义,是相反的。。
ref: 化解冲突:git merge 与 git rebase 中的 ours 和 theirs
42. git stash 贮藏的使用
考虑这样的场景:
场景1:在master执行过git commit,随后改了一些内容,但是不足以(或不想)提交为一次commit(包括没有git add的,也包括没有git commit的),但此时又不得不切换到另一个分支做其他事情。当前分支的修改,怎样处理比较好?
场景2:把代码上传到了github等remote,然后在家里和公司两台电脑A和B上都可以展开工作,某天在公司电脑B上提交了代码到github,而回到家里A电脑执行git pull时,发现昨天因为家里网络不好,A电脑上有未曾git add的代码,并且这些修改也不想作为一次commit,而git pull则提示需要贮藏。
所谓贮藏,可以理解为当前git repo有一个stack,可以存储临时的更改。既然是stack,可以存放多个这样的修改。
基本用法步骤:
# 贮藏当前没有git add和没有git commit的修改
git stash # 或 git stash push
# 列出所有贮藏
git stash list
# 丢弃最近一次贮藏
git stash pop
# 应用一次贮藏。但是都是作为没有git add的效果(没有暂存)
git stash apply
# 应用一次贮藏,并且区分了是否有暂存的情况
git stash apply --index