如题

windows 版工具下载

  1. 点击进入 Git for Windows 官网
  2. 点击进入 TortoiseGit for Windows 官网

在windows下,为不同的项目设置不同的用户名,linux下类似

  1. 用 notepad++ 编辑项目根目录下.git/config,在最后添加:

    1
    2
    3
    [user]
    name = yourName
    email = yourEmail
  2. 文件夹.git是隐藏文件夹,如果看不到,需要设置显示隐藏文件夹。

  3. 添加之后,在commit和push的时候就不会串了。

git基本操作

如果是 windows 环境,在项目所在文件夹下,右键->Git Bash Here,在出来的命令窗口进行后续操作。

命令 解释
git clone url 从url克隆项目。
git clone -b branchName url 从url克隆项目的分支
git status 查看当前状态。
git add -A 或者 git add . 把改变的文件放到暂缓区。
git commit 提交到本地文件库。
git commit -m ‘备注信息` 提交的同时,添加备注,这样就不会出现 vim 编辑。
git pull 在 push 前,建议先再执行 git pull 命令获取最新,如果有冲突,会提示 merge。直接 pull 其实也没问题,如果有冲突,也会提示需要 merge,只是建议先 merge 再 push。
git push 将本地修改过并且 commit 过的文件推到 git 服务器。
git branch -v 查看本地项目分支情况
git branch -r 查看远端库的分支情况
git branch -a -a 参数可以查看远程和本地分支,远程分支会用红色表示出来(如果你开了颜色支持的话)
git branch --set-upstream-to=origin/dev 建立本地 dev 分支到上游(远端)仓的链接,这样代码才能提交上去
git branch --unset-upstream master 取消对master的跟踪
git branch <new-branch-name> <tag-name> 从 tag 创建新分支
git branch -d dev 删除本地分支 dev
git push origin --delete dev 删除远端分支 dev
git tag v1.0 轻量级标签。实际上就是一个保存着对应提交对象的校验和信息的文件。要创建这样的标签,一个 -a,-s 或 -m 选项都不用,直接给出标签名字即可
git tag -a v1.1 -m "my version 1.1" 含附注的标签。创建标签 v1.1,用 -a (译注:取 annotated 的首字母)指定标签名字,-m 选项则指定了对应的标签说明
git fetch upstream 获取主分支的最新修改到本地
git merge upstream/master 将upstream分支修改内容 merge 到本地个人分支
git checkout -b v2.0.0 从已有的分支 master 创建新的 v2.0.0 分支,并切换至新分支 v2.0.0,相当于两个命令:git branch v2.0.0; git checkout v2.0.0;
git push --set-upstream origin v2.0.0 提交新分支 v2.0.0 至远端,注意:set-upstream 前面是两个中杠字符,在网页看,不明显
git push origin v2.0.0 提交新分支至远端,经测试,与上面的命令等效,具体有什么差别,还没深入研究。
git checkout master 切换回 master 分支
git checkout dev 切换至 dev 分支
git merge dev 将 dev 分支合并到当前分支
git push origin dev 提交 dev 分支到远程仓库
git push origin newBranch 把本地创建的 newBranch 分支提交到远程仓库
git push --tags 把本地 tag 推送到远程
git fetch origin tag <tagname> 获取远程 tag
git fetch origin master 从远程获取最新版本到本地,不会自动merge,需要注意的是: 和push不同, fetch会自动获取远程[新加入]的分支.
git remote add [shortname] [url] 添加远程仓库
git remote show [shortname] 查看远程仓库信息
git remote rename [old-name] [new-name] 重命名远程仓库
git remote rm [shortname] 删除远程仓库(解除与远程仓库的关系)

创建 tag

Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。
lightweight :轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。
annotated:含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。

一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。

含附注的标签
创建一个含附注类型的标签非常简单,用 -a (译注:取 annotated 的首字母)指定标签名字即可
而 -m 选项则指定了对应的标签说明,Git 会将此说明一同保存在标签对象中。如果没有给出该选项,Git 会启动文本编辑软件供你输入标签说明。(git 提交注释都是-m ‘XXxx’)

1
2
3
4
$ git tag v1.0 -m '2018-06-26 1.0 版本'                                                 
AndyChen@AndyChen MINGW64 /c/workspace/source (master)
$ git tag
v1.0

由 master 创建新分支 v2.1 并提交至远端

1
2
git checkout -b v2.1
git push origin v2.1

将 master 的修改同步/合并(merge)到 v2.1

1
2
3
4
5
git checkout master
git pull
git checkout v2.1
git merge master
git push -u origin v2.1

git clone

  • git clone git_仓库_url 获取全部branch内容,整体下载时间较长 & 所占磁盘空间较大
  • git clone -b git_分支名称 git_仓库_url 根上述 1. 结果一致
  • git clone -b git_分支名称 –single–branch git_仓库_url 获取指定分支的代码
  • git clone –depth 10 git_仓库_url 只会获取最近 xx(10条提交记录的)代码,默认是master分支, 如果想要指定分支,可以结合 -b –single–branch 使用!

reference

Git 基础 - 打标签
Git 分支 - 分支的新建与合并
Git 分支 - 分支开发工作流

git clone 指定分支

如果不指定分支,默认是 master 分支,而如果库里没有 master 这个默认分支,则会得到下面的错误信息。

1
2
3
4
5
6
remote: Counting objects: 13978, done.
remote: Compressing objects: 100% (672/672), done.
remote: Total 13978 (delta 1219), reused 1566 (delta 1079), pack-reused 12201
Receiving objects: 100% (13978/13978), 9.23 MiB | 1.46 MiB/s, done.
Resolving deltas: 100% (9473/9473), done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

这个时候,就需要指定一个存在的分支来 clone。
git clone -b 分支名 仓库地址
git clone -b Router https://github.com/user/project.git

提交代码时,写备注

  1. 在 git commit 之后会出现一个 vim 编辑框,按 ESC 可以退出当前编辑,然后输入 wq 回车,表示保存并退出,输入 q! 表示不保存并退出。这个 vim 编辑窗口的操作命令跟 linux 下的 vim 是一样的。

撤销 git commit 但是未 git push 的修改

如果不小心 commit 了一次不需要 commit 的修改,可以对其进行撤销。
先使用 git log 查看 commit 日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git log
commit f20c593a52b21c53b9c5ad831068697ebe1b4d21
Author: AndyChen <1614923608@qq.com>
Date: Thu May 18 22:11:47 2017 +0800

test

commit 7b39f469f3751bddbca59c3eae05c3288a469c7f
Author: AndyChen <1614923608@qq.com>
Date: Thu May 18 22:09:54 2017 +0800

Initial commit

AndyChen@AndyChen-PC MINGW64 /d/dev.workspace/myself/mytest (master)
$

  • 退出,输入 q

找到需要回退到的那次 commit 的 hash 值,上面的例子,hash 值为 7b39f469f3751bddbca59c3eae05c3288a469c7f
记住,不是错误 commit 的那次的 hash 值(上面的例子,是:f20c593a52b21c53b9c5ad831068697ebe1b4d21),而是错误 commit 之前 commit 的 hash 值,也就是你希望回退到哪次,就选哪次的 hash 值

错误 commit 那次的 hash 值是:f20c593a52b21c53b9c5ad831068697ebe1b4d21
错误 commit 那次的 hash 值是:f20c593a52b21c53b9c5ad831068697ebe1b4d21

1
2
3
4
5
$ git reset --hard 7b39f469f3751bddbca59c3eae05c3288a469c7f
HEAD is now at 7b39f46 Initial commit

AndyChen@AndyChen-PC MINGW64 /d/dev.workspace/myself/mytest (master)
$

执行上面的命令之后,从提示也能看出来,已经回退到“Initial commit”那个版本了,之前日志为“test”的提交被删除,相应的代码修改将会丢失。

撤销 git commit 且已经 git push 的修改

把上面的 git reset 改为 git revert
revert 后,本地代码会回滚到指定的历史版本,再 git push 既可推送到线上
不过,revert 方式会有冲突,更直接的方式:checkout 该版本之后,再恢复线上的 .git 即可提交。这种方式会保留之前的所有提交记录。

第三方 windows 客户端工具

  1. 用过 SVN 的童鞋,估计大多数都用过小乌龟客户端 TortoiseSVN,其实小乌龟客同样有 Git 的客户端:TortoiseGit。操作跟 TortoiseSVN 基本一样,用过 TortoiseSVN 的童鞋几乎不用学就会用了,什么?没用过?从下面的下载链接下载并安装之后,你在项目文件夹点右键试试…
  2. 猛戳进入下载页面

github 上 fork 一个分支之后,如何和主分支同步

github fork 一个分支后,如果过一段时间就会和主分支的差异比较大。 这样提交 pr 的时候就会冲突,这个时候我们就需要和主分支同步代码
下面,以项目 https://github.com/uncleAndyChen/springBootIntegrationUEditor 为例

1
2
3
4
git remote add upstream git@github.com:uncleAndyChen/springBootIntegrationUEditor.git
git fetch upstream
git merge upstream/master
git push

TortoiseGit-git did not exit cleanly (exit code 1)

如果服务器有更新没有同步到本地,同时本地又有新的修改没有 commit,则在 push 本地 commit 的时候会报这个错误。
解决办法,把本地所有修改 commit,然后 pull, 再 push.

git clone 报错: fatal: The remote end hung up unexpectedly

reference: https://segmentfault.com/q/1010000007502362
?

1
2
3
git repack -a -f -d --window=250 --depth=250

git clone git@github.com:username/repo

报错信息:

1
2
fatal: The remote end hung up unexpectedly
...

进行全局设置

1
2
git config --global http.postBuffer 1048576000
#git config --global core.compression 9 # 最大压缩,会让传输文件变小

配置git的最低速度和最低速度时间 单位 秒:

1
2
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999

错误信息变成:

1
2
3
4
5
6
remote: Enumerating objects: 692, done.
Receiving objects: 28% (199/692), 19.96 MiB | 47.00 KiB/s
error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

主要原因是安全设置的问题:
执行 git config --global http.sslVerify "false"

不过,以上方法都试过了,还是报下面的错误

1
2
3
4
5
6
Cloning into 'comparing_images'...
remote: Enumerating objects: 692, done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

网上有人说继续加大 http.postBuffer 的值,于是我再加大10倍,git config --global http.postBuffer 1048576000,这下错误又变回之前发行过的错误信息了:

1
2
3
4
5
6
Cloning into 'comparing_images'...
remote: Enumerating objects: 692, done.
error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

git无法断点续传的下载办法:git fetch git

reference:https://blog.csdn.net/Sayai/article/details/81452496

创建一个空目录,进入该目录,执行 git init

1
2
git fetch git://github.com/userName/repoName   # 用http也会断,只有用git才行。如果还是断了,重复执行该命令。不过,有网友反映:再次执行git fetch还是重新下载
git checkout FETCH_HEAD  # 成功提取也就ok了。

中间可能碰到权限问题,需要去git上增加一个ssh的key
Please make sure you have the correct access rights and the repository exists.
命令行执行以下语句

1
2
3
git config --global user.name 【你的登录用户】
git config --global user.email 【你的注册邮箱】
ssh-keygen -t rsa -C "your@email.com"   # 等待提示,然后输入yes

按照提示去目标的.ssh文件夹下找到id_rsa.pub文件,用记事本打开,拷贝全部内容。
打开https://github.com/,登陆你的账户,进入设置,然后是SSH and GPG keys
New SSH Key 把刚刚拷贝的内容贴进去,title随便起。
回到命令行中执行:ssh -T git@github.com
等待提示出现后,输入yes。
然后可以继续刚刚命令行的步骤了。

后续步骤

等到fetch完会出现以下字样

1
2
From git://….
*branch HEAD -> FETCH_HEAD

如:

1
2
3
4
5
6
7
8
remote: Enumerating objects: 53, done.
remote: Counting objects: 100% (53/53), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 664 (delta 50), reused 50 (delta 50), pack-reused 611
Receiving objects: 100% (664/664), 74.66 MiB | 13.00 KiB/s, done.
Resolving deltas: 100% (360/360), done.
From git://github.com/vzat/comparing_images
* branch HEAD -> FETCH_HEAD

意思是把最新的数据fetch到了本地的FETCH_HEAD分支上去了
然后用git checkout FETCH_HEAD切换至该分支即可。

指定分支,并仅克隆最近一次提交,以减小下载文件大小,同时交款 https 换成 git 方式

1
git clone -b master git://github.com/UserName/repoName --depth 1

还是会遇到中断:

1
2
3
4
5
6
remote: Enumerating objects: 129, done.
remote: Counting objects: 100% (129/129), done.
remote: Compressing objects: 100% (124/124), done.
fatal: The remote end hung up unexpectedlyB | 6.00 KiB/s
fatal: early EOF
fatal: index-pack failed

当重复执行上述命令时,还是会从头开始下载,并未断点续传。

remove remote branch?

reference:https://blog.csdn.net/worn_xiao/article/details/79233983
同样的指令只是少了个空格 结果却不尽相同。
本意是更新远程分支,结果却是删除原有的分支

1
2
$git push origin A:B
$git push origin A :B

只克隆最近一次commit以减小下载文件大小

git clone https:xxx.git –depth 1
depth用于指定克隆深度,为1即表示只克隆最近一次commit.

git config –add core.compression -1

compression 是压缩的意思,从 clone 的终端输出就知道,服务器会压缩目标文件,然后传输到客户端,客户端再解压。取值为 [-1, 9],-1 以 zlib 为默认压缩库,0 表示不进行压缩,1..9 是压缩速度与最终获得文件大小的不同程度的权衡,数字越大,压缩越慢,当然得到的文件会越小。

git submodule

git clone –recursive 用于循环克隆git子项目

git submodule -> 子项目

git submodule 使用小结

克隆一个包含子仓库的仓库目录,并不会clone下子仓库的文件,只是会克隆下.gitmodule描述文件,需要进一步克隆子仓库文件。

1
2
3
4
5
// 初始化本地配置文件
$ git submodule init

// 检出父仓库列出的commit
$ git submodule update

或者使用组合指令。

1
$ git submodule update --init --recursive

git 强制 pull

1
2
3
git fetch --all 
git reset --hard origin/master
git pull

推送本地分支到远程新分支上面去

git push origin local_branch:remote_branch
这个操作,local_branch必须为你本地存在的分支,remote_branch为远程分支,如果remote_branch不存在则会自动创建分支。

操作示例:

1
2
3
4
5
$ git push origin master:v2.3.1
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered By Gitee.com
To https://gitee.com/uncleAndyChen/ant-design-pro-official.git
* [new branch] master -> v2.3.1

HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large

1
2
3
4
5
6
7
8
9
10
Enumerating objects: 107, done.
Counting objects: 100% (107/107), done.
Delta compression using up to 16 threads
Compressing objects: 100% (102/102), done.
Writing objects: 100% (102/102), 670.98 MiB | 14.64 MiB/s, done.
Total 102 (delta 11), reused 0 (delta 0)
error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large
fatal: the remote end hung up unexpectedly
fatal: the remote end hung up unexpectedly
Everything up-to-date

原因:仓库的大小超过了 gitee 的限制。

解决

  • 当然是取消大文件的提交。
    • 如果在本地已经有大文件 commit,哪怕你在 push 时遇到错误,然后把大文件删除,再 commit,接着 push,也还是会报这个错的。
    • 因为还是会把之前添加大文件的 commit 提交,然后再提交删除大文件的提交。

可以通过命令把之前添加大文件的 commit 删除掉,不过这个过程有一点复杂,具体脚本这里就是写了,百度一下。这里建议重新拉取项目,把除了添加大文件之外的修改同步一下再提交(commit 后 push)。

Out of memory, malloc failed (tried to allocate 1895825408 bytes) failed to push some refs

当内存使用接近100%时,git push 会报错,解决方案是关掉一些应用释放内存占用再操作。

1
2
3
4
Delta compression using up to 8 threads. 
Out of memory, malloc failed (tried to allocate 1895825408 bytes) failed to push some refs
to 'https://gitee.com/uncleAndyChen/tech.git'
The remote end hung up unexpectedly sha1 file ' ' write error: Broken pipe

colliding group is in the working tree

1
2
3
warning: the following paths have collided (e.g. case-sensitive paths
on a case-insensitive filesystem) and only one from the same
colliding group is in the working tree:

原因是服务器上有两个目录 wechat 和 weChat,而本地的是 weChat,而 windows 文件系统对大小写不敏感,所以会有这个问题,在这个问题解决之前,修改的文件提交会失败:

1
2
3
4
14:56	Commit failed with error
0 files committed, 1 file failed to commit: improve
On branch master
Your branch is up to date with 'origin/master'.

解决:
以管理员身份运行Windows PowerShell
执行命令:Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
这个时候会提示是否重启,输入 “Y” 回车执行重启。
重启完以后,继续以管理员身份运行Windows PowerShell,开始设置目录区分大小写,比如出现问题的那个目录是 C:\workspace\wechat
那么执行命令:fsutil.exe file setCaseSensitiveInfo C:\workspace\wechat

只是需要注意的是,这样的解决办法只对当前目录有效,而对其子目录并无作用。

git 查看 config 配置信息

config 配置指令

1
git config --system/global/local 具体配置项 配置项值

如:

1
2
git config --global user.name "AndyChen"
git config --global user.email "552087293@qq.com"

config 配置的三个级别

  1. system
  2. global(用户级别)
  3. local(当前仓库)

设置优先级,由低到高为:system -> global -> local,底层配置会覆盖顶层配置。

查看系统 config

1
git config --system --list

查看当前用户(global)配置

1
git config --global  --list

查看当前仓库配置信息

1
git config --local  --list

查看具体的设置项

1
git config --system/global/local 具体配置项

比起设置配置项,不要后面的值即可。如查看 global user.nameglobal user.email 的设置项:

1
2
3
4
5
C:\Users\Andy>git config --global user.name
AndyChen

C:\Users\Andy>git config --global user.email
552087293@qq.com

error: bad signature 0x00000000

在用 vs code 获取最新代码时,悲剧的事情发生了—电脑蓝屏,重启电脑后,再次获取最新,提示:error: bad signature 0x00000000

1
2
3
C:\workspace\project>git pull
error: bad signature 0x00000000
fatal: index file corrupt

解决

在 windows 下的话,推荐用 Git Bash,好处是可以执行 unix 下的指令。到项目根目录,执行:rm -f .git/indexgit reset

1
2
3
4
5
6
7
8
9
10
11
12
andy@AndyChen MINGW64 /c/workspace/project (master)
$ rm -f .git/index

andy@AndyChen MINGW64 /c/workspace/project (master)
$ git reset
Unstaged changes after reset:
M config/config.ts
M src/pages/home/data.source.js

andy@AndyChen MINGW64 /c/workspace/project (master)
$ git pull
Already up to date.

git 不区分文件名大小写

环境

windows 10 64 位

现象

在 Vscode 下开发,有两个组件,文件名首字母是小写,后来发现组件名的首字母应该大写,所以,就改为大写了,但是提交之后,发现文件名被改
回去了,也就是首字母又被改为小写了,导致引用的地方提示找不到文件。

如果不是因为代码检查未通过,阻止了提交,那么,如果直接提交的后果:虽然本地可以区分大小写,但是推送到远端会发现存在两个文件,一个是大写,一个是小写。此时当别人克隆该项目时,发现克隆下来的还是修改前的文件。

解决方法:使用 git rm -r --cached <文件> 删掉修改前的文件,提交然后推送到远端。如此操作之后,远端就只有一个修改之后的文件了,改名之前的文件已经被删除。

解决大小写不敏感的问题

设置 git 库为大小写敏感

  • 到项目根目录下执行:git config core.ignorecase false
  • 找到项目的 .git 文件夹(window默认是隐藏的,设置显示隐藏的项目即可出现) 下的 config 文件打开,将 ignorecase = true 设置成 ignorecase = false

比较笨的方式

  • 先删除文件,提交,再添加文件,然后提交。
  • 使用git mv命令:git mv A.js a.js。注意:仅当git config core.ignorecase true时可用,否则会提示错误:fatal: destination exists, source=A.js, destination=a.js

git mv 不能直接修改文件夹名的大小写

1
2
git mv B b                                   
fatal: renaming 'B' failed: Invalid argument

可以先改名为其它的,然后再改回去,如:

1
2
git mv B abc
git mv abc b

设置区分大小写

  • 全局设置:git config --global core.ignorecase false
  • 不过,全局设置没有对项目生效,空了研究,记得到每个项目根目录下执行第一条指令,即:git config core.ignorecase false

在项目下设置,针对项目

1
2
3
4
# 查看
git config core.ignorecase
# 设置
git config core.ignorecase false

全局开启区分大小写

1
2
3
4
# 查看
git config --global core.ignorecase
# 设置
git config --global core.ignorecase false

查看所有配置

1
git config --list

查看大小写配置

1
git config --get core.ignorecase

windows10 下大小写冲突问题

  • 冲突的两个目录下的同名文件,比较了几个,内容完全一样,汗~~
    1
    2
    3
    4
    5
    6
    7
    # git clone 有警告
    warning: the following paths have collided (e.g. case-sensitive paths on a case-insensitive filesystem)
    and only one from the same colliding group is in the working tree:
    ...
    'pagesTask/custom/custom.js'
    'pagestask/custom/custom.js'
    ...

解决

需要在冲突的两个文件夹中,删除一个,保留另外一个,不过,得先把代码完整 clone 下来才能操作

1
2
C:\workspace\frontend>git config --get core.ignorecase
false

git 全局配置已经是大小写敏感了,看来跟这个配置无关,应该是之前提交代码的时候“埋”的雷~~

1
2
fsutil file SetCaseSensitiveInfo C:\workspace\frontend enable
错误: 不支持该请求。

windows 下的操作

控制面板 -> 程序 -> 程序和功能 -> 启动或关闭 windows 功能 -> 勾选:用于Linux的Windows子系统,需要重启

1
2
3
4
5
6
C:\Windows\system32>fsutil file SetCaseSensitiveInfo C:\workspace\frontend enable
已启用目录 C:\workspace\frontend 的区分大小写属性。

# 到需要启动大小写敏感的目录下执行
C:\workspace\frontend>fsutil file SetCaseSensitiveInfo ./ enable
已启用目录 C:\workspace\frontend\ 的区分大小写属性。

通过以上操作之后,重新 clone 代码,没有再出现之前的 case-insensitive filesystem 警告,出现了之前冲突的文件夹

正常情况下,不会出现以上问题,无须过多关心