我读到在Git中重命名文件时,你应该提交任何更改,执行重命名,然后展示重命名的文件。Git将从内容中识别文件,而不是将其视为一个新的未跟踪的文件,并保留更改历史。
然而,今晚这样做,我最终恢复到git mv。
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
我重命名我的样式表在Finder从iphone.css到mobile.css:
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: css/iphone.css
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# css/mobile.css
所以Git现在认为我删除了一个CSS文件,并添加了一个新的文件。这不是我想要的。让我们撤销重命名,让Git来完成这项工作。
> $ git reset HEAD .
Unstaged changes after reset:
M css/iphone.css
M index.html
我又回到了开始的地方:
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
让我们用git mv代替:
> $ git mv css/iphone.css css/mobile.css
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: css/iphone.css -> css/mobile.css
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.html
#
看起来我们没事了。那么,为什么Git在我第一次使用Finder时没有识别出这个重命名呢?
当我把我的文件夹和文件大写时,我使用Node.js的文件系统来解决这个问题。
在开始之前,不要忘记做出承诺。我不确定它有多稳定:)
在项目根中创建脚本文件。
// File rename.js
const fs = require('fs').promises;
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const args = process.argv.slice(2);
const path = args[0];
const isCapitalized = (s) => s.charAt(0) === s.charAt(0).toUpperCase();
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
async function rename(p) {
const files = await fs.readdir(p, { withFileTypes: true });
files.forEach(async (file) => {
const { name } = file;
const newName = capitalize(name);
const oldPath = `${p}/${name}`;
const dumbPath = `${p}/dumb`;
const newPath = `${p}/${newName}`;
if (!isCapitalized(name) && name !== 'i18n' && name !== 'README.md') {
// 'git mv' won't work if we only changed size of letters.
// That's why we need to rename to dumb name first, then back to current.
await exec(`git mv ${oldPath} ${dumbPath}`);
await exec(`git mv ${dumbPath} ${newPath}`);
}
if (file.isDirectory()) {
rename(newPath);
}
});
}
rename(path);
重命名目录(或单个文件)脚本中的所有文件更简单:
// rename.js
const fs = require('fs').promises;
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const args = process.argv.slice(2);
const path = args[0];
async function rename(p) {
const files = await fs.readdir(p, { withFileTypes: true });
files.forEach(async (file) => {
const { name } = file;
const currentPath = `${p}/${name}`;
const dumbPapth = `${p}/dumb`;
await exec(`git mv ${currentPath} ${dumbPath}`);
await exec(`git mv ${dumbPath} ${currentPath}`);
if (file.isDirectory()) {
rename(newPath);
}
});
}
rename(path);
运行带有参数的脚本
node rename.js ./frontend/apollo/queries
如何使用Node.js运行shell脚本文件或命令