目录

Git 的一些命令笔记

基础

克隆仓库

1
git clone <repo.git>

获取远程分支 master 并 merge 到当前分支

1
git pull origin master

创建本地分支,并切换到新创建分支

1
git checkout -b <new_branch> [origin/<start_branch>]

添加标签,增加 v1.0 的 tag 到某个提交上

1
git tag v1.0 \<hash\>

将当前版本重置为 HEAD

1
git reset --hard HEAD

强制推送分支到远程仓库

当推送时遇到,Updates were rejected because the tip of your current branch is behind 时可以使用

1
git push -u origin master -f

通过 rebase 进行 squash

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 查看下起源避免出错
git remote -v
# 切换到自己的项目分支
git checkout ChangeBadCode
# 查看下日志,并判断需要将多少个日志合并
git log
# 把顶部的六个版本聚到一起进入编辑页面
git rebase -i HEAD~6
# 进入编译模式,根据需要,修改每行行首的pick,如果需要squash,则将原来的pick都改为s。
# 同时必须保留一个pick,否则提交会报错。
# 如果提交过程出错,可以使用
git rebase --continue
# 继续编辑,或使用
git rebase --abort
# 取消此次操作

检出变动的文件并打包

1
git diff commit_1 commit_2--name-only | xargs zip update.zip

整理仓库

删除文件

1
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <filename>' --prune-empty --tag-name-filter cat -- --all

删除文件夹

1
git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch <dirname>' --prune-empty --tag-name-filter cat -- --all

删除 storage 文件夹下所有的 log 文件

1
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch storage/logs/*.log' --prune-empty --tag-name-filter cat -- --all

删除回收

1
2
3
4
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

创建空白分支

1
git checkout --orphan emptybranch 

按特定时间提交

1
GIT_COMMITTER_DATE="2020-10-10T10:10:10" git commit --amend --date="2020-10-10T10:10:10"

SVN

克隆

1
git svn clone --username=xxxxxx <repo_url>

提交代码

1
git svn dcommit

撤销提交

1
git reset --soft HEAD^
  • 传参解释
1
2
3
4
5
6
7
8
9
--mixed 
# 【默认参数】不删除工作空间改动代码,撤销commit,并且撤销git add .。

--soft  
# 不删除工作空间改动代码,撤销commit,不撤销git add .。
 
--hard
# 删除工作空间改动代码,撤销commit,撤销git add .。
# 注意完成这个操作后,就恢复到了上一次的commit状态。

换行符

Refer: https://docs.github.com/en/github/getting-started-with-github/getting-started-with-git/configuring-git-to-handle-line-endings

背景

Windows 下默认的文本换行符是 \r\n,Linux 下默认的换行符是 \n,M 下默认的换行符是 \r(后来和 Linux 系统保持一致)。

Git 为了解决不同平台换行符不一致的问题,在 Windows 操作系统中默认在检出代码时默认会将 LF 转换为 CRLF,而在提交的时候再转换为 LF,但在实际场景中该转换并不能很好的处理各种场景下的换行符问题。

char short full remark
\r CR Carriage-Return 回车
\n LF Line-Feed 换行
\r\n CRLF Carriage-Return Line-Feed 回车换行

解决方案

全局参数

Git 中有三个参数于换行符有关:

  • eol: 设置工作目录中文件的换行符,有三个值 lf, crlf 和 native(默认,同操作系统)
  • autocrlf: true 表示检出时转换 CRLF, 提交时转换为 LF false 表示不做转换 input 表示检出时不转换,提交时转换为 LF
  • safecrlf: true 表示不允许提交时包含不同换行符 false 则允许提价时有不同换行符存在 warn 则只在有不同换行符时警告

配置方法:

1
2
3
4
5
6
# 统一换行符为 lf
git config --global core.eol lf
# 将自动转换关闭,避免转换失败不能不同进行提交
git config --global core.autocrlf false
# 禁止混用 lf 和 crlf 两种换行符
git config --global core.safecrlf true

或修改 .gitconfig, 添加如下内容:

1
2
3
4
[core]
	eol=lf
	autocrlf=false
	safecrlf=true

仓库级配置

虽然通过设置了 Git 全局参数解决了问题,但是作为团队协作的话,并不能保证所有人都正确配好了。Git 提供了 .gitattributes 文件解决了这个问题。在项目根目录新建 .gitattributes 文件,添加以下内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Set the default behavior, in case people don't have core.autocrlf set.
* text eol=lf

# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.h text

# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

通过该配置可以避免协作者没有设置 core.autocrlf 参数而导致换行符问题。 同时,可以根据需要在项目不同目录中创建 .gitattributes 文件,当对应文件设置为二进制文件后,Git 则不再考虑换行符问题。

转换现有仓库

对于现有 Repo, 在 Linux 下推荐使用 dos2unix 工具,该工具在 Mac 中可以使用 brew 安装,而 Windows 系统中 Git Bash 自带了该工具。

以转换项目中 php 源代码为例:

1
2
cd <project_path>
find . -type file -name '*.php' -exec dos2unix {} +

或者执行:

1
git add --renormalize .

编辑器配置

  • vscode

file: settings.json

1
2
3
{
  "files.eol": "\n",
}

Q&A

Windows 下,error: unable to create file **: Filename too long

以管理员方式进入 cmd ,运行如下命令:

1
git config --system core.longpaths true