设置默认上传当前分支
这是一个很好用的功能,如我现在已经切换到了 t/lindexi/f1 分支,我想要将这个分支推送到 remote 默认需要这样写
git push origin t/lindexi/f1
如果设置了默认推送当前分支,那么代码将会变得十分简单,每次使用 git push 都会自动上传 CurrentBranch 现在的分支
git config --global push.default current
这个配置加上了 --global
对本机的所有仓库都有用,将可以在仓库里面输入 git push
就自动推送当前分支,减少了命令行很多代码
从一个远程分支推送另一个远程分支
如何使用 git 在两个远程仓库之间,将一个远程分支推送另一个远程分支
比如我想将 github 仓库上的远程分支,推送到我 gitlab 仓库上的分支,过程中我不希望将我 github 的分支切到本地
先假定 remote 名为 github 的为 github 仓库,名为 gitlab 的为 gitlab 仓库。希望推送的是 t/lindexi/foo
分支。则推送命令如下
git fetch github
git push gitlab github/t/lindexi/foo:refs/heads/t/lindexi/foo
推送的语法是
git push [被推送的仓库名] [源远程仓库名]/[分支名]:refs/heads/[分支名]
核心语法在需要加上 refs/heads/
到命令上,如没有加入,则会提示如下错误
error: The destination you provided is not a full refname (i.e.,
starting with "refs/"). We tried to guess what you meant by:
- Looking for a ref that matches 't/lindexi/foo' on the remote side.
- Checking if the <src> being pushed ('refs/remotes/github/t/lindexi/foo')
is a ref in "refs/{heads,tags}/". If so we add a corresponding
refs/{heads,tags}/ prefix on the remote side.
Neither worked, so we gave up. You must fully qualify the ref.
hint: The <src> part of the refspec is a commit object.
hint: Did you mean to create a new branch by pushing to
hint: 'refs/remotes/github/t/lindexi/foo:refs/heads/t/lindexi/foo'?
error: failed to push some refs to 'gitlab.lindexi.com:lindexi/Lindexi.git'
提交出现 TaskCanceledException
如果提交出现异常 Fatal: TaskCanceledException encountered
这是 git 的问题,尝试升级最新的 git 或输入git config --global credential.helper wincred
就可以让 git 记住密码
合并多个分支的时候不要自动合并
每次在合并 csproj 文件的时候自动合并都会让项目难以编译,如果需要让 git 合并多个分支的时候不要自动合并,发现有文件都有修改的时候就让开发自己解决,请使用下面的命令
git merge origin/xx --strategy=resolve
这里的命令的使用需要先使用 git fetch --all -p
让远程的分支最新,然后调用 merge 合并对应的分支
git fetch --all -p
git merge 仓库/分支名 --strategy=resolve
Cherry-pick 多个提交
如果多个提交是连续的,那么可以使用下面的方法git cherry-pick 开始...结束
例如有提交
76a0298d38760a635f404c1660238ae852d96517 提交 4
55b43be69fa90f4d03f27632c0231458ba1e7fd9 提交 3
55b43be69fa90f4d03f27632c0231458ba1e7fd9 错误的提交
e50b523f12d34435b3b49fe229d76ecc4754687f 提交 2
322d49c166b0a48bdcc6c1f69b29c617b435850b 提交 1
8793f59a87cbc4c62cf77b21369de657dc343a5d 提交 0
需要挑拣出 提交0-4 那么一般的方法是使用 git cherry-pick
5次。但是有一个简单的方法,只需要pick两次
git 的 pick 可以指定范围,下面的代码告诉大家如何使用
git cherry-pick 8793f59a87cbc4c62cf77b21369de657dc343a5d^...e50b523f12d34435b3b49fe229d76ecc4754687f
//8793f59a87cbc4c62cf77b21369de657dc343a5d 提交 0
//e50b523f12d34435b3b49fe229d76ecc4754687f 提交 2
git cherry-pick 55b43be69fa90f4d03f27632c0231458ba1e7fd9...76a0298d38760a635f404c1660238ae852d96517
//55b43be69fa90f4d03f27632c0231458ba1e7fd9 错误的提交
//76a0298d38760a635f404c1660238ae852d96517 提交 4
可以看到第一个代码存在^
,因为pick的范围是(左开,右闭]
,所以为了包含 提交0 ,就需要在提交0添加^
。第二个提交从 55b43be69fa90f4d03f27632c0231458ba1e7fd9 错误的提交 开始,因为左开右闭,不会包含这个提交。
git 删除不需要的分支
git branch --merged | grep -v 'dev' | xargs -n 1 git branch -d
可以删除已经合并的分支
git 删除仓库的 tag
删除 origin 仓库的 tagname 可以使用下面代码
git push origin :tagname
也可以使用 --delete
删除
git push --delete origin tagname
删除本地 tag 可以使用
git tag --delete tagname
https://stackoverflow.com/a/5480292/6116637
git 删除本地所有 Tag 号
git tag | xargs git tag -d
git 推送所有 Tag 号
git push --tags
快速推送刚打出来的 Tag 可以采用先删除本地所有的 Tag 号,然后再打出一个 Tag 推送所有 Tag 号
git 取消暂存
如果错误 add 不想添加的文件,可以使用下面命令取消添加文件
git reset .
如果有 f1 f2 两个文件,错误把两个文件都使用 add 暂存,现在只需要添加 f1 那么可以使用下面代码
git reset f2
使用方法:
git reset 文件名
如果需要查看现在暂存的文件,可以使用下面代码
git status
git 寻找提交所在的分支
使用下面的代码可以找到提交所在的分支
git branch --contains <commit>
如果需要找到远程分支,加添加-r
,请看下面
git branch -r --contains <commit>
git worktree 添加已有分支的空间
使用下面代码可以使用已有分支添加空间
git worktree add <文件夹> 分支
或
git worktree add -b <新分支名> <新路径> <从此分支创建>
在 VisualStudio 添加 Blame
在 VisualStudio ,我看到了自带的 Blame 很烂,于是如何在 VisualStudio 添加一个强大的 Blame?
我选择了deepgit ,我把它安装在 C 盘,安装完成可以使用外部命令把他放在 VisualStudio,下面就是方法
-
确定 deepgit 的路径,记为 path ,我这里的是
C:\Program Files (x86)\DeepGit\bin\deepgit.exe
-
打开 VisualStudio 工具 外部工具
-
点击添加
-
输入标题,标题可以随意写。命令就是 path 安装路径,参数写
$(ItemPath)
- 点击添加或移除按钮 自定义
- 添加命令 这里选择工具的外部命令4,外部命令和添加命令所在有关,我这里添加的是第4个
git 列出所有的 subtree
请使用下面代码列出
git log | grep git-subtree-dir | tr -d ' ' | cut -d ":" -f2 | sort | uniq
git 添加 subtree 项目
请使用下面代码将某个项目添加
git subtree add --prefix=用来放某个项目的相对路径 某个项目git地址 某个项目的某个分支
git 推送 subtree
可以使用下面的代码推送
git subtree --prefix="路径" push origin dev
分离分支
git subtree split [--rejoin] --prefix=<本地子项目目录> --branch <主项目中作为放置子项目的分支名>
拉取项目
git subtree add --prefix <本地子项目目录> <远程仓库> <远程分支>
git subtree -P <本地子项目目录> pull <远程仓库> <远程分支>
需要知道 使用-P
和使用--prefix
是相同的,使用--branch
和使用-b
是相同的
只有第一次拉取才需要使用 git subtree add
命令
git tag 添加说明
如果对于一个分支的提交,需要添加tag而且给说明,如
v1.1 添加游戏
那么可以使用下面的命令
git tag v1.1 -m "添加游戏"
这样就会拿分支最后一次提交添加 tag 加上说明
git 指定文件夹
如果是在程序使用 git ,需要指定 git 的文件夹。
例如我在程序使用了 git add .
那么 git 怎么知道是添加哪个文件夹,如果没有告诉 git 就会添加程序运行的文件夹
例如添加 E:\林德熙\代码
文件夹,可以使用下面代码
git -C "/e/林德熙/代码" add .
使用 -C 文件夹路径
就可以让 git 添加指定的文件夹。但是在 Windows 下的路径,需要自己转换,完全不如代码调用传入工作路径。也就是将 git 的工作路径,修改为对应的文件夹。如此可以不使用 -C
参数
创建本地仓库
如果需要创建本地仓库,只需要创建一个文件夹,然后在文件夹里使用下面代码
git init
这样就可以创建,但是现在创建的仓库无法被push代码,如果使用 push 到这个文件夹的代码,就会出现下面代码
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: is denied, because it will make the index and work tree inconsistent
解决方法是在刚才创建的本地仓库文件夹使用下面代码
git config --bool core.bare true
或者在创建文件夹之后,使用下面代码初始化
git init --bare
这时本地的文件夹是无法看到文件的,原来显示文件的 git checkout .
执行会显示下面代码
This operation must be run in a work tree
因为设置了bare
所以无法使用,如果要使用,就需要先去掉,使用下面代码
git config --unset core.bare
如果想要看到文件,需要执行下面两句代码
git config --unset core.bare
git checkout .
注意,设置了git config --unset core.bare
就无法再push任何东西,需要再设置git config --bool core.bare true
才可以
git log
计算 git 的提交数
使用下面代码可以计算提交数
git rev-list --all --count
计算 Git 的提交距离
下面代码的写法就是从 21a2b79331 距离 origin/dev 的提交数
git rev-list --count origin/dev ^694b319f24
查找一个文件的追踪变更
将一个文件挪动文件夹,默认不会显示此文件移动文件夹之前的 commit 记录。如果想要获取整个文件的历史记录,需带上 --follow
参数,如下面命令
git log --follow Program.cs
以上的 Program.cs 文件即使被我多次移动文件夹,也能获取到历史
如何在Git中查看已删除文件的历史内容记录
命令行如下
git log --all -- [已删除的文件的路径]
比如已知名为 Foo.cs 文件被删除了,可以使用以下命令找到这个文件的历史记录
git log --all -- Foo.cs
以上日志可以输出 Foo.cs 的历史记录,可根据其历史记录的 commit 切换到历史版本,找回原来的文件
还可以在 --all
后面带上 --full-history
参数
找到被删除的文件
从历史提交里面找到被删除的文件
git log --all --full-history -- <path-to-file>
文件支持通配如知道文件叫 xx.cs 可以使用下面的代码找到这个文件
git log --all --full-history -- **/xx.cs
https://stackoverflow.com/a/7203551/6116637
拷贝一个文件保持其历史记录
在 git 里面没有提供将一个文件拷贝为两个且保留这两个文件的历史记录
通过 How to duplicate a file while preserving git line history - The Old New Thing 的方法即可让 git 拷贝一个文件时,让历史记录存在两个文件里面,不会让拷贝的文件丢失历史记录
假定有一个名为 foods 的文件,准备将其拷贝出一个名为 foods-new 的新文件,要求 foods 和 foods-new 文件都能在 git log --follow <文件名>
命令里获取其历史记录
可以使用如下命令进行复制,如果你不熟悉 git 的话,按照我以下提供的命令一句句敲进去,只替换其中的文件名即可
先切换出一个分支,将在这个分支执行拷贝逻辑。切换分支只是为了如果命令执行失败了,好切换回原来的分支,不会弄坏。如果你是熟练工的话,不切分支也没问题
git checkout -b dup
使用 git mv 命令,先将 foods 文件移动(改名)为 foods-new 文件
git mv foods foods-new
此时的 foods 文件将不存在,但没关系,咱在后续步骤会将其恢复。现在先执行 commit 命令将其签入,命令如下
git commit -m "duplicate foods to foods-new"
完成签入之后,使用以下命令进行 foods 文件还原
git checkout HEAD~ foods
再对其进行签入
git commit -m "restore foods"
此时两个文件已经保持好了历史记录且完成拷贝
大家可以使用 git log --follow <文件名>
命令看看这两个文件是否保留了历史记录
由于上述步骤咱切换了分支,接下来使用如下命令切换回原有的分支,且合入当前的拷贝
git checkout -
git merge --no-ff dup
如果熟练工没有新建分支的话,那不需要执行切换回原有的分支
Git 只需要 commit 号
想要让 Git 的 Log 输出的只有 commit 号而没有其他内容,可以使用下面命令
git log --pretty=format:%H
输出格式如下
964568b1bbc042b1a5f4d3109103022d9d089b0d
693fec8423b3a6c5cc760d345dbd668a69c03c81
7eb048730fbedd26b691271349088b5c5f6b39d3
如果需要的是短的 commit 内容,可以将 H
替换为 h
如下面命令
git log --pretty=format:%h
输出格式如下
964568b
693fec8
7eb0487
设置只对 github 开启代理
请将 socks5://127.0.0.1:1080 换你本地代理
git config --global http.https://github.com.proxy socks5://127.0.0.1:10112
取消设置
git config --global --unset http.https://github.com.proxy
统计更改文件
统计被更改的文件可以使用下面代码
git status | grep 'modified:' | wc -l
在使用 git status
会显示版本里面被当前修改的文件,需要通过 git add 添加的文件有哪些是被修改,然后通过过滤修改统计修改的文件
让 Tag 按照创建时间排序
git tag --sort=-creatordate
使用别名优化命令
Git 并不会在你输入部分命令时自动推断出你想要的命令。 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名。 这里有一些例子你可以试试:
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
以下是我配置的别名:
// 让 Tag 按照创建时间排序
git config --global alias.ts 'tag --sort=-creatordate'
// 提内容
git config --global alias.cm 'commit -m'
Filename too long
先注册表开启长路径支持
使用 win+r 运行,输入 regedit 回车打开注册表
进入 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
路径
右键新建一个名为 LongPathsEnabled 的 DWORD 项,配置其为 1 的值。详细请参阅 Maximum Path Length Limitation - Win32 apps Microsoft Learn
打开 git bash 输入以下命令行
git config --system core.longpaths true
接着重启电脑即可。重启电脑是因为 LongPathsEnabled 配置是带缓存的,没有重启电脑是无效的
如何删除错误提交的 git 大文件
git无法pull仓库refusing to merge unrelated histories
git subtree pull 错误 Working tree has modifications
git 提交添加 emoij 文字
git cannot lock ref
git 修改commit日期为之前的日期
git镜像仓库
git 合并两个仓库
git 分支改名
git push 错误 hook declined
git 上传当前分支
git 合并工具
参见:
再也不用克隆多个仓库啦!git worktree 一个 git 仓库可以连接多个工作目录 - CSDN博客
git fatal detected dubious ownership in repository 的解决方法
github 解决推拉代码提示 REMOTE HOST IDENTIFICATION HAS CHANGED 失败
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/git-%E9%9C%80%E8%A6%81%E7%9F%A5%E9%81%93%E7%9A%841000%E4%B8%AA%E9%97%AE%E9%A2%98.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。
无盈利,不卖课,做纯粹的技术博客
以下是广告时间
推荐关注 Edi.Wang 的公众号
欢迎进入 Eleven 老师组建的 .NET 社区
以上广告全是友情推广,无盈利