我读到在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时没有识别出这个重命名呢?


当前回答

步骤1:将文件从oldfile重命名为newfile

git mv #oldfile #newfile

步骤2:git提交并添加注释

git commit -m "rename oldfile to newfile"

步骤3:将此更改推到远程服务器

git push origin #localbranch:#remotebranch

其他回答

当我把我的文件夹和文件大写时,我使用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脚本文件或命令

刚刚遇到了这个问题-如果你更新了一堆文件,不想把它们都做git mv,这也可以:

将父目录/dir/RenamedFile.js重命名为/whatever/RenamedFile.js。 git添加-A来进行更改 重命名父目录为/dir/RenamedFile.js。 git add -A再次,将重新stage vs该更改,迫使git拾取文件名更改。

最好的办法是自己去试试。

mkdir test
cd test
git init
touch aaa.txt
git add .
git commit -a -m "New file"
mv aaa.txt bbb.txt
git add .
git status
git commit --dry-run -a

现在git状态和git提交——dry-run -a显示两个不同的结果,其中git状态显示bbb.txt作为一个新文件/ aaa.txt被删除,而——dry-run命令显示实际的重命名。

~/test$ git status

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   bbb.txt
#
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    aaa.txt
#


/test$ git commit --dry-run -a

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    aaa.txt -> bbb.txt
#

现在去办理登机手续。

git commit -a -m "Rename"

现在您可以看到文件实际上已重命名,并且git status中显示的内容是错误的,至少在本例中是这样。下划线GIT实现可能会将这两个命令分开处理。

这个故事的寓意:如果你不确定你的文件是否被重命名了,发出一个“git commit -dry-run -a”。如果它显示文件已重命名,那么就可以开始了。

对于Git 1.7。下面的命令对我有用:

git mv css/iphone.css css/mobile.css
git commit -m 'Rename folder.'

不需要添加git,因为原始文件(即css/mobile.css)已经在之前提交的文件中。

步骤1:将文件从oldfile重命名为newfile

git mv #oldfile #newfile

步骤2:git提交并添加注释

git commit -m "rename oldfile to newfile"

步骤3:将此更改推到远程服务器

git push origin #localbranch:#remotebranch