Git设置以及常用命令

免密码,一键上传

Views:  times Updated on February 19, 2024 Posted by elmagnifico on November 3, 2015

Git Bash 修改默认打开文件夹位置

Win10下

如何让Git Bash打开的时候直接进入项目目录,而不是每次都要去cd…

  • 方法一

git的安装目录下搜索 bashrc

然后编辑文本,最后一行加上

#后面接你自己的项目目录就行了
cd e:\Github\elmagnificogi.github.io\

但是这样有个一个问题,不管从哪里打开git bash,或者是右键从here 打开git bash 都会转到自己的项目目录去,很不方便,所以不推荐这个方法。

  • 方法二

直接对着Git Bash 快捷方式右键-属性

起始位置:填入你要到的目录

比如:

e:\Github\elmagnificogi.github.io\

这样的 然后应用-确定 再打开就发现直接到了自己想去的目录,也不会影响 git bash here命令了。

  • 后话

刚开始不知道方法二,看到了右键-快捷方式-目标

D:\Git\git-bash.exe --cd-to-home

以为修改后面的home就能实现更改默认目录呢 死活改不对(闪退),直到发现方法二,才发现白费功夫啊。

Git Push 不用每次输入账号和密码

Win10下

每次都要输入用户名密码,我的f键还有点问题,经常输入的时候f键按了,但是没输入进去,导致一遍遍重输入账号密码,都快吐血了(后来直接在记事本里写好账号密码,然后输入的时候直接复制粘贴)

那如何解决这个问题呢?

最简单的方法

git config --global credential.helper store

然后随便改点什么进行一次提交,即可,用户名和密码就已经记住了

方法一

在windows中添加一个HOME环境变量(注意不是系统变量哦)

变量名:HOME

变量值:%USERPROFILE%

然后进入 %HOME% 目录(直接复制到地址栏就能进去了)

新建一个名为_netrc的文件,文件中内容格式如下: (一定要注意这个文件没有后缀名!显示一下后缀名确保正确!)

machine github.com
login 你的账户
password 你的密码

重开git bash 再次push 你会发现不要账号和密码了

方法二

如果方法一没用的话再尝试方法二

打开git bash 在%HOME% 的目录下 创建.git-credentials文件

先去看看自己的 %HOME% 是在哪里 然后再用下面的命令不然就无效

touch .git-credentials

vim .git-credentials

文本内容为:

https://你的账户:你的密码@github.com

重开git bash 再次push 你会发现不要账号和密码了

实际上git config --global credential.helper store就是完成上述操作而已

github库一键更新上传

每次都得输入

git add .
git commit -m "update-post"
git push origin master

好麻烦,得弄个什么一键完成比较快,刚好也不用输入账号密码,省事

找了找,应该写一个update.sh来完成就可以了 于是如下:

git add .;
git commit -m "update-post";
git push origin master

以后只需要调用

./update.sh

就可以完成所有操作啦。

git cmd

add

git add .

把添加文件改动添加到缓存区中,就是为了添加新文件而生的

commit

git commit  -am "提交信息记录"

把改动提交到缓冲区中,其中-m是为了有提交记录,-a是了只提交被删除或者修改了的文件。

而新添加的文件是不会被加入到HEAD区中的,新添加的需要用add来完成。

push

把本地分支推送到远端某个分支

push origin local_branch:remote_branch

默认推送远端同名分支

push origin local_branch

clone

git clone <版本库地址>
git clone <版本库的网址> <本地目录名>

我自己用的:

git clone https://github.com/elmagnificogi/elmagnificogi.github.io

直接克隆一个当前最新的版本的blog下来。

一般经常会遇到提示克隆的目录不为空,这种情况都是直接删除整个目录重新克隆一下就好了

如果感觉速度太慢了,那就挂代理克隆

pull

git pull

直接从远程更新,并且合并到本地库中。如果想要对比一下,然后合并则不能用这个。

而且不安全,除非你自己保证本地的是比远程的老,并且没有任何新内容才能用

Git fetch origin master
git log -p master..origin/master
git merge origin/master

而用fetch就是只从远程取到本地,但是并不进行融合,也就是说不会覆盖本地的内容。

然后进行对比之后,再融合。

checkout

git checkout new_branch

从当前分支切换到new_branch分支中去。

git checkout -- test.txt

虽然不加–也可以完成这个操作,用来从最新的commit中恢复test.txt文件,但是为了避免歧义

有可能他会识别文件明和分支名相同的情况,从而去切换分支了

merge

git merge old_branch

这里是将old_branch分支合并到当前目录的分支中,有可能会出现冲突

git diff <source_branch> <target_branch>

查看分支的不同之处,进而合并分支,有必要时需要使用 add来添加文件

解决冲突

通过命令行选择我方或者对方的冲突点,而不手动修改每个文件

# 冲突全部选择当前分支
git checkout --ours <fileName>
# 或者冲突全部选择对方分支
git checkout --theirs <fileName>

# 解决完冲突,加入更新
git add <fileName>
# 继续下一个冲突
git rebase --continue
# 查看下一个冲突点
git status

status

git status

查看当前分支的状态,会显示增删改的文件

log

git log

可以查看你之前commit的记录

git log --pretty="%h - %s" -n 1

获取最近的一条commit id和信息

reflog

git reflog

可以查看所有的提交删除相关的改变 Head 的记录,用于平时回到最新版时查找最新的commit号

reset

git reset --hard commit号

强制退回到某个版本,删除该版本之后所有的commit

revert

git revert commit号

回滚到某个版本,会提交一个回滚commit

git reset --hard origin/main

强制本地分支与远端main相同

rebase

如果想要将某个commit中历史中抹除,就好像什么都没发生过一样

git rebase -i commit_id

commit_id是要删除的那个commit之前的一个commit,然后进入修改历史页面,将要删除的commit_id 由pick修改为drop,其他保持不变即可

rebase一般是在feature分支中,为了同步最新的主分支,而使用rebase

git checkout feature1
git ...
...

# 同步最新的主分支
git rebase

然后就会将主分支的所有commit一个个重放,如果出现冲突就要求解决

squash

squash是用于合并多个commit的,类似于开发某个feature,但是实际这个分支上可能提交了10个commit,但是合并到主分支的时候,其实主分支只关心这个feature而不是内部的10个commit细节。此时为了保证主分支的简洁性,就有了Squash,它可以把10个commit压缩成一个commit 提交到主分支。

但是squash本质上是个commit标记,实际操作的时候依然需要配合rebase一起使用

# 变基
git rebase -i HEAD~5

# 交互编辑下,将其他commit标记位squash
pick 123456 Commit 1
squash 234567 Commit 2
squash 345678 Commit 3
squash 456789 Commit 4
squash 567890 Commit 5

stash

git stash save "work in progress for foo feature"

保存当前的所有修改,存在 stash 中,并退回最近的一个版本

git stash list

显示当前 stash 中保存的所有版本

git stash apply stash@{1}

把 stash 中编号为1的版本恢复出来

submodule

有时候clone的工程里有submodule,这个时候submodule的工程都不会自动关联下载的。

要我们指定下载,如下即可自动递归寻找需要下载的子模块

git submodule update --init --recursive

submodule 移动位置,目前看到的大多数移动submodule都不太正确。

git 从1.8.5开始支持快捷移动了,直接就能完成submodule的位置移动

git mov old/subxxx new/subxxx
  • 但是这里有一个小问题,就是submodule的别名其实用的还是老路径,奇奇怪怪的,其他的倒是没问题

老方法移动submodule,其实也很简单,删除submodule,提交,然后去新位置再拉一次submodule,提交,不好的地方就是凭空多了2个没啥用的commit

branch

git checkout -b newpro

新建一个叫newpro的分支 并且切换过去

git branch

可以查看本地有什么分支,当前分支会带*号

git branch newpro

新建一个叫newpro的分支,但是不会切换过去

cherry-pick

将其他分支上的某个commit合并到主分支上时,需要使用cherry-pick

合并前

a - b - c - d   Master
 \
  e - f - g     Feature
git checkout master
git cherry-pick f

合并后

a - b - c - d - f   Master
 \
  e - f - g         Feature

cherry-pick不仅仅可以选某个commit,也可以整个分支进行合并,有点merge的意思,也可以输入多个commit,进行合并

tag

git tag xxx

给当前分支的commit打标签为xxx

git tag -d xxx

删除标签为xxx的tag

git pull --tags

拉取所有tag,建议直接使用fetch,简单方便

git fetch origin --tags --force

强制使用远端的tag覆盖本地已经存在的tag

git push origin tag_name -f

强制推送本地的tag,更新远端的

git describe --tags --always --abbrev=0 HEAD

获取最近的tag

assume-change

平常都是用.gitignore来忽略文件的,但是如果我本地修改了,但是我又不想他被提交,而且是经常都忽略他的修改,要怎么方便的处理这个问题。

我一直都在找有没有让git单次追踪的方法,只追踪这个文件第一次,后续全都忽略,找了半天没找到

发现可以使用assume-change直接假设这个文件没有发生变化,此时修改了文件,使用git status也会看到啥都没改的提示

git update-index --assume-unchanged .obsidian/workspace.json
或者
git update-index --skip-worktree 指定你的文件

要恢复追踪,使用下面的命令即可

git update-index --no-assume-unchanged 文件名
git update-index --no-skip-worktree 文件名

显示有哪些文件被暂时忽略了

window环境
git ls-files -v | findstr /B h 			列出 assume-unchanged
git ls-files -v | findstr /B S  		列出 skip-worktree
linux环境
git ls-files -v|grep "^h"
git ls-files -v|grep "^S"

skip和assume的区别在于skip会尽力保证你拉取新代码时也能暂时忽略,而assume则是会被远端代码直接覆盖,导致assume失效。skip在合并的时候可能会出现冲突,需要人为解决。

常见问题

图形化界面

gitk

图形化上面的各种命令和对比,更加直观。

git中文乱码

git config --global gui.encoding utf-8

修改编码模式即可

修改commit的编码模式,这样同步仓库也是一样的

git config --global i18n.commitencoding utf-8

git status中文乱码

git config --global core.quotepath false

beyond compare作为冲突解决工具

首先看一下当前版本的git比较工具有哪些

$ git difftool --tool-help

'git difftool --tool=<tool>' may be set to one of the following:
                vimdiff2
                vimdiff3

The following tools are valid, but not currently available:
                bc3
                gvimdiff
                gvimdiff2
                gvimdiff3
                nvimdiff
                nvimdiff2

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.

可以看到有个bc3,gvimdiff,nvimdiff,bc3就是beyond compare,新版本的git可能还会有bc4

看一下当前版本的git合并工具有哪些,理论上应该是和difftool一样的

$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
                vimdiff2
                vimdiff3

The following tools are valid, but not currently available:
                bc3
                gvimdiff
                gvimdiff2
                gvimdiff3
                nvimdiff
                nvimdiff2

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.

设置diff工具为BComp.exe,注意不是BCompare.exe

git config --global diff.tool bc3
git config --global difftool.bc3.path "D:/BCompare/BComp.exe"

同理设置merge工具

git config --global merge.tool bc3
git config --global mergetool.bc3.path "D:/BCompare/BComp.exe"

设置好了以后直接git mergetool就可以看到启动的是BCompare.exe

也可以通过直接修改.gitconfig全局设置,直接设置路径,全局文件路径是C:\Users\用户名

[diff]
	tool = bc3
[merge]
	tool = bc3
[mergetool "bc3"]
	path = D:/BCompare/BComp.exe
[difftool "bc3"]
	path = D:/BCompare/BComp.exe

git无法使用ctrl+c退出

造成这个应该是key hook出问题了,这个问题反复发生,目前最新的git又无法退出了,解决这个问题只能回退一个老版本的git

https://github.com/waylau/git-for-win

目前我能确定的是2.30.0这个版本是没问题的

image-20230331162500123

git 无法识别大小写

由于windows本身对于文件名的大小写不敏感,导致实际上如果把原本大写名称改成小写或者反过来,git是不会认为文件修改了的。

而如果代码后续存储到了linux或者其他unix系统中,大小写是敏感的,这就会导致无法识别,缺少文件。

要让git对文件大小写敏感,可以使用下面的代码,修改设置即可

git config core.ignorecase false

Quote

http://blog.csdn.net/on_1y/article/details/19259435

http://www.cnblogs.com/lixiaolun/p/4360732.html

http://blog.163.com/023_dns/blog/static/1187273662013111301046930/

http://www.cnblogs.com/ballwql/p/3462104.html

http://blog.csdn.net/wh_19910525/article/details/7784901

https://support.huaweicloud.com/usermanual-codehub/devcloud_hlp_0957.html

https://blog.csdn.net/weixin_44799217/article/details/128279250

https://blog.csdn.net/cookcyq__/article/details/121918646

https://zhuanlan.zhihu.com/p/557663152

https://stackoverflow.com/questions/10663527/how-to-move-git-submodule-to-sub-directory