跳到主要内容

2 篇博文 含有标签「Git」

查看所有标签

· 阅读需 3 分钟
绝尘

背景

在 Windows 系统上进行前端开发时,通常使用 Git 进行版本控制,并使用 Prettier 进行代码格式化。跨平台协作中,不同操作系统对换行符的处理方式不同:

  • CRLF\r\n):Windows 系统默认使用
  • LF\n):Unix/Linux/Mac 系统使用

前端项目通常统一使用 LF 换行符,以保持代码一致性。

问题

在 Windows 上开发时,遇到以下问题:

  1. Git 自动转换:执行 git pull 后,文件行尾字符自动从 LF 变回 CRLF
  2. Prettier 报错:格式化时提示 Warning: Line endings should be LF, but CRLF found
  3. 配置无效:即使配置了 core.autocrlf=false 也可能无效

解决方案

一、Prettier 配置

.prettierrcpackage.json 中配置:

{
"endOfLine": "lf"
}

批量修复现有文件:

npx prettier --write "**/*.{js,jsx,ts,tsx,json,css,scss,md}"

二、Git 配置

1. 全局配置

git config --global core.autocrlf false
git config --global core.eol lf

2. 项目级配置(可选)

git config core.autocrlf false
git config core.eol lf

3. 创建 .gitattributes 文件

在项目根目录创建 .gitattributes

* text=auto eol=lf
*.sh text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary

4. 修复已存在的文件

git rm --cached -r .
git reset --hard
git add .gitattributes
git add -A
git commit -m "统一使用 LF 行尾字符"

5. 验证配置

# 查看配置
git config --global --list | grep -E "autocrlf|eol"

# 检查文件行尾
git ls-files --eol

三、完整操作流程

按以下步骤执行:

# 1. 全局配置 Git
git config --global core.autocrlf false
git config --global core.eol lf

# 2. 创建 .gitattributes 文件(内容见上文)

# 3. 修复现有文件
git rm --cached -r .
git reset --hard
git add .gitattributes
git add -A
git commit -m "统一使用 LF 行尾字符"

# 4. 使用 Prettier 格式化修复换行符
npx prettier --write "**/*.{js,jsx,ts,tsx,json,css,scss,md}"

注意事项

  • .gitattributes 优先级最高,会覆盖 core.autocrlfcore.eol 配置
  • 团队需要统一配置,避免不同开发者之间的冲突
  • 规范化操作会改变文件内容,团队成员需要重新拉取代码

· 阅读需 5 分钟
绝尘

在项目迭代过程中,随着代码量与模块复杂度不断攀升,将一个大型 Git 工程拆分为多个独立工程,能让项目结构更清晰,便于团队协作与维护。关键是要保留完整的提交历史,这就需要借助 Git 的 filter-branch 工具来实现。

一、准备工作

使用 filter-branch

git filter-branch 是 Git 内置的强大工具,无需额外安装,可以直接使用。虽然相比 filter-repo 效率稍低,但功能完整且稳定可靠。

验证可用性:

git filter-branch --help

备份原仓库

拆分前务必备份原仓库,防止操作失误导致数据丢失:

git clone --mirror 原仓库地址 备份仓库地址

二、拆分示例

假设原仓库有两个独立模块,需拆分为:

  • 工程 A:只保留 module-a/ 目录及相关历史
  • 工程 B:只保留 module-b/ 目录及相关历史

三、具体步骤

拆分工程 A

1. 克隆原仓库

git clone 原仓库地址 工程A
cd 工程A

2. 使用 filter-branch 保留指定目录

git filter-branch --prune-empty --subdirectory-filter module-a master

参数说明:

  • --subdirectory-filter module-a:将 module-a 目录作为新仓库的根目录
  • --prune-empty:删除空提交
  • master:指定要重写历史的分支

3. 清理无关分支(可选)

# 查看所有分支
git branch -a

# 删除不需要的分支
git branch -D 无关分支名
git branch -dr origin/无关分支名

4. 提交到新仓库

# 关联新仓库
git remote add origin 工程A的新仓库地址

# 推送所有分支和标签
git push -u origin --all
git push --tags

拆分工程 B

按照相同步骤操作:

# 重新克隆原仓库
git clone 原仓库地址 工程B
cd 工程B

# 只保留 module-b 目录
git filter-branch --prune-empty --subdirectory-filter module-b master

# 关联工程 B 的远程仓库并推送
git remote add origin 工程B的新仓库地址
git push -u origin --all
git push --tags

四、重要说明

历史完整性

filter-branch 会重写提交历史,只保留与指定目录相关的提交(包括修改、删除、重命名等操作),其他提交会被过滤,最终历史记录"干净"且相关。

处理大型仓库

若仓库体积大(含大量大文件),可先清理超大文件:

# 使用 filter-branch 清理大文件
git filter-branch --tree-filter 'rm -f large_file.zip' HEAD

高级用法

filter-branch 提供了多种过滤方式:

按文件大小过滤:

git filter-branch --tree-filter 'find . -size +10M -delete' HEAD

按文件类型过滤:

git filter-branch --tree-filter 'rm -rf *.log' HEAD

保留多个目录:

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch module-c module-d' HEAD

五、高级用法

复杂目录结构拆分

如果需要拆分更复杂的目录结构,可使用以下方法:

使用 tree-filter 进行复杂操作:

# 只保留特定文件类型
git filter-branch --tree-filter 'find . -name "*.js" -o -name "*.ts" | xargs rm -f' HEAD

# 排除特定目录
git filter-branch --tree-filter 'rm -rf temp/ build/ node_modules/' HEAD

# 重命名目录结构
git filter-branch --tree-filter 'mkdir -p new_structure && mv module-a/* new_structure/' HEAD

使用 index-filter 提高性能:

# 只保留指定目录(性能更好)
git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch module-b module-c' HEAD

通过以上步骤,两个新工程会分别保留原仓库中与自身模块相关的完整提交历史,且相互独立。这样既保持了代码的连续性,又实现了模块的独立管理。