git 如何跟踪未跟踪的内容?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4161022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:27:44  来源:igfitidea点击:

How to track untracked content?

gitgit-submodules

提问by sscirrus

See below the solid line for my original question.

请参阅以下实线以了解我的原始问题。

I have a folder in my local directory that is untracked. When I run git status, I get:

我的本地目录中有一个未跟踪的文件夹。当我运行时git status,我得到:

Changed but not updated:
modified:   vendor/plugins/open_flash_chart_2 (modified content, untracked content)

When I type git add vendor/plugins/open_flash_chart_2then try git statusagain, it still says untracked. What's going on?

当我输入git add vendor/plugins/open_flash_chart_2然后再试git status一次时,它仍然显示未跟踪。这是怎么回事?



Here is a simple summary of my latest half hour:

这是我最近半小时的简单总结:

  • Discovered that my Github repo is not tracking my vendor/plugins/open_flash_chart_2plugin. Specifically, there's no content and it's showing a green arrowon the folder icon.

  • Tried git submodule init

    No submodule mapping found in .gitmodules for path 'vendor/plugins/open_flash_chart_2'
    
  • Tried git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

    vendor/plugins/open_flash_chart_2 already exists in the index
    
  • git status

    modified: vendor/plugins/open_flash_chart_2 (untracked content)
    
  • Hunted for any file named .gitmodulesin my repository/local directory but couldn't find one.

  • 发现我的 Github 存储库没有跟踪我的vendor/plugins/open_flash_chart_2插件。具体来说,没有内容,它在文件夹图标上显示一个绿色箭头

  • 试过 git submodule init

    No submodule mapping found in .gitmodules for path 'vendor/plugins/open_flash_chart_2'
    
  • 试过 git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

    vendor/plugins/open_flash_chart_2 already exists in the index
    
  • git status

    modified: vendor/plugins/open_flash_chart_2 (untracked content)
    
  • 寻找.gitmodules在我的存储库/本地目录中命名的任何文件,但找不到。

What do I have to do to get my submodules workingso git can start tracking properly?

我该怎么做才能让我的子模块正常工作,这样 git 才能开始正确跟踪?



This may be unrelated (I include it in case it helps), but every time I type git commit -arather than my usual git commit -m "my comments", it throws up an error:

这可能是无关的(我包括它以防它有帮助),但是每次我输入git commit -a而不是我通常的输入时git commit -m "my comments",它都会抛出一个错误:

E325: ATTENTION
Found a swap file by the name ".git\.COMMIT-EDITMSG.swp"
         dated: Thu Nov 11 19:45:05 2010
     file name: c:/san/project/.git/COMMIT_EDITMSG
      modified: YES
     user name: San   host name: San-PC
    process ID: 4268
While opening file ".git\COMMIT_EDITMSG"
         dated: Thu Nov 11 20:56:09 2010
  NEWER than swap file!  
Swap file ".git\.COMMIT_EDITMSG.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
Swap file ".git\.COMMIT_EDITMSG.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:

I am a complete newbie at Github and despite trying to go through the documentation, I'm a bit stumped by these particular problems. Thank you.

我是 Github 的完全新手,尽管我试图阅读文档,但我还是被这些特殊问题难住了。谢谢你。

回答by Chris Johnsen

You have added vendor/plugins/open_flash_chart_2as “gitlink” entry, but never defined it as a submodule. Effectively you are using the internal feature that git submoduleuses (gitlink entries) but you are not using the submodule feature itself.

您已添加vendor/plugins/open_flash_chart_2为“gitlink”条目,但从未将其定义为子模块。实际上,您正在使用git submodule使用的内部功能(gitlink 条目),但您没有使用子模块功能本身。

You probably did something like this:

你可能做了这样的事情:

git clone git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2
git add vendor/plugins/open_flash_chart_2

This last command is the problem. The directory vendor/plugins/open_flash_chart_2starts out as an independent Git repository. Usually such sub-repositories are ignored, but if you tell git addto explicitly add it, then it will create an gitlink entry that points to the sub-repository's HEAD commit instead of adding the contents of the directory. It might be nice if git addwould refuse to create such “semi-submodules”.

最后一个命令是问题所在。该目录vendor/plugins/open_flash_chart_2最初是一个独立的 Git 存储库。通常这样的子存储库会被忽略,但是如果您告诉git add显式添加它,那么它将创建一个 gitlink 条目,指向子存储库的 HEAD 提交,而不是添加目录的内容。如果git add拒绝创建这样的“半子模块”可能会很好。

Normal directories are represented as tree objects in Git; tree objects give names, and permissions to the objects they contain (usually other tree and blob objects—directories and files, respectively). Submodules are represented as “gitlink” entries; gitlink entries only contain the object name (hash) of the HEAD commit of the submodule. The “source repository” for a gitlink's commit is specified in the .gitmodulesfile (and the .git/configfile once the submodule has been initialized).

普通目录在 Git 中表示为树对象;树对象为其包含的对象提供名称和权限(通常是其他树和 blob 对象——分别是目录和文件)。子模块表示为“gitlink”条目;gitlink 条目仅包含子模块的 HEAD 提交的对象名称(哈希)。gitlink 提交的“源存储库”在.gitmodules文件中指定(以及.git/config子模块初始化后的文件)。

What you have is an entry that points to a particular commit, without recording the source repository for that commit. You can fix this by either making your gitlink into a proper submodule, or by removing the gitlink and replacing it with “normal” content (plain files and directories).

您拥有的是一个指向特定提交的条目,而无需记录该提交的源存储库。您可以通过将 gitlink 放入适当的子模块,或通过删除 gitlink 并将其替换为“正常”内容(纯文件和目录)来解决此问题。

Turn It into a Proper Submodule

把它变成一个合适的子模块

The only bit you are missing to properly define vendor/plugins/open_flash_chart_2as a submodule is a .gitmodulesfile. Normally (if you had not already added it as bare gitlink entry), you would just use git submodule add:

您唯一缺少正确定义vendor/plugins/open_flash_chart_2为子模块的部分是.gitmodules文件。通常(如果您还没有将其添加为裸 gitlink 条目),您只需使用git submodule add

git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

As you found, this will not work if the path already exists in the index. The solution is to temporarily remove the gitlink entry from the index and then add the submodule:

如您所见,如果该路径已存在于索引中,这将不起作用。解决办法是暂时从索引中删除gitlink条目,然后添加子模块:

git rm --cached vendor/plugins/open_flash_chart_2
git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

This will use your existing sub-repository (i.e. it will not re-clone the source repository) and stage a .gitmodulesfile that looks like this:

这将使用您现有的子存储库(即它不会重新克隆源存储库)并暂存一个如下所示的.gitmodules文件:

[submodule "vendor/plugins/open_flash_chart_2"]
    path = vendor/plugins/open_flash_chart_2
    url = git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2

It will also make a similar entry in your main repository's .git/config(without the pathsetting).

它还将在您的主存储库中创建一个类似的条目.git/config(没有path设置)。

Commit that and you will have a proper submodule. When you clone the repository (or push to GitHub and clone from there), you should be able to re-initialize the submodule via git submodule update --init.

提交它,您将拥有一个适当的子模块。当您克隆存储库(或推送到 GitHub 并从那里克隆)时,您应该能够通过git submodule update --init.

Replace It with Plain Content

用纯内容替换它

The next step assumes that your sub-repository in vendor/plugins/open_flash_chart_2does not have any local history that you want to preserve (i.e. all you care about is the current working tree of the sub-repository, not the history).

下一步假设您的子存储库中vendor/plugins/open_flash_chart_2没有任何您想要保留的本地历史记录(即您只关心子存储库的当前工作树,而不是历史记录)。

If you have local history in the sub-repository that you care about, then you should backup the sub-repository's .gitdirectory before deleting it in the second command below.(Also consider the git subtreeexample below that preserves the history of the sub-repository's HEAD).

如果您关心的子存储库中有本地历史记录,那么您应该备份子存储库的.git目录,然后在下面的第二个命令中将其删除。(还要考虑下面的git subtree示例,它保留了子存储库的 HEAD 的历史记录)。

git rm --cached vendor/plugins/open_flash_chart_2
rm -rf vendor/plugins/open_flash_chart_2/.git # BACK THIS UP FIRST unless you are sure you have no local changes in it
git add vendor/plugins/open_flash_chart_2

This time when adding the directory, it is not a sub-repository, so the files will be added normally. Unfortunately, since we deleted the .gitdirectory there is no super-easy way to keep things up-to-date with the source repository.

这次添加目录的时候,不是子仓库,所以文件会正常添加。不幸的是,由于我们删除了.git目录,因此没有超级简单的方法来使源存储库保持最新状态。

You might consider using a subtree mergeinstead. Doing so will let you easily pull in changes from the source repository while keeping the files “flat” in your repository (no submodules). The third-party git subtreecommandis a nice wrapper around the subtree merge functionality.

您可以考虑改用子树合并。这样做可以让您轻松地从源存储库中提取更改,同时保持存储库中的文件“扁平”(无子模块)。第三方git subtree命令是子树合并功能的一个很好的包装器。

git rm --cached vendor/plugins/open_flash_chart_2
git commit -m'converting to subtree; please stand by'
mv vendor/plugins/open_flash_chart_2 ../ofc2.local
git subtree add --prefix=vendor/plugins/open_flash_chart_2 ../ofc2.local HEAD
#rm -rf ../ofc2.local # if HEAD was the only tip with local history

Later:

之后:

git remote add ofc2 git://github.com/korin/open_flash_chart_2_plugin.git
git subtree pull --prefix=vendor/plugins/open_flash_chart_2 ofc2 master

git subtree push --prefix=vendor/plugins/open_flash_chart_2 [email protected]:me/my_ofc2_fork.git changes_for_pull_request

git subtreealso has a --squashoption that lets you avoid incorporating the source repository's history into your history but still lets you pull in upstream changes.

git subtree还有一个--squash选项,可以让您避免将源存储库的历史记录合并到您的历史记录中,但仍然允许您引入上游更改。

回答by neoneye

I just had the same problem. The reason was because there was a subfolder that contained a ".git" folder. Removing it made git happy.

我只是遇到了同样的问题。原因是因为有一个包含“.git”文件夹的子文件夹。删除它让 git 很高兴。

回答by user2041369

  1. I removed the .git directories from those new directories (this can create submodule drama. Google it if interested.)
  2. I then ran git rm -rf --cached /the/new/directories
  3. Then I re-added the directories with a git add . from above
  1. 我从这些新目录中删除了 .git 目录(这可以创建子模块戏剧。如果有兴趣,请谷歌一下。)
  2. 然后我运行 git rm -rf --cached /the/new/directories
  3. 然后我用 git add 重新添加了目录。从上面

Reference URL https://danielmiessler.com/blog/git-modified-untracked/#gs.W0C7X6U

参考网址https://danielmiessler.com/blog/git-modified-untracked/#gs.W0C7X6U

回答by Peter Lada

To point out what I had to dig out of Chris Johansen's chat with OP (linked from a reply to an answer):

指出我必须从 Chris Johansen 与 OP 的聊天中挖掘出的内容(链接自对答案的回复):

git add vendor/plugins/open_flash_chart_2# will add gitlink, content will stay untracked

git add vendor/plugins/open_flash_chart_2# 将添加 gitlink,内容将不被跟踪

git add vendor/plugins/open_flash_chart_2/# NOTICE THE SLASH!!!!

git add vendor/plugins/open_flash_chart_2/# 注意斜线!!!!

The second form will add it without gitlink, and the contents are trackable. The .git dir is conveniently & automatically ignored. Thank you Chris!

第二种形式会在没有gitlink的情况下添加,内容是可追踪的。.git 目录可以方便地自动忽略。谢谢克里斯!

回答by Eloici

I use the trick suggested by Peter Lada all the time, dubbed as "fake submodules":

我一直使用 Peter Lada 建议的技巧,称为“假子模块”:

http://debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb

http://debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb

It's very useful in several scenarios (p.e. I use it to keep all my Emacs config in a repository, including the current HEAD of all git repositories inside the elpa/el-get package directories, so I could easily roll back/forward to a known working version when some update breaks something).

它在几个场景中非常有用(我用它来将我所有的 Emacs 配置保存在一个存储库中,包括 elpa/el-get 包目录中所有 git 存储库的当前 HEAD,所以我可以轻松地回滚/前进到一个已知的当某些更新破坏某些内容时的工作版本)。

回答by nicolas

I had the same problem with a big project with many submodules. Based on the answers of Chris Johnsenhereand VonChereI build a short bash script which iterates through all existing gitlink entries and adds them as proper submodules.

我在一个包含许多子模块的大项目中遇到了同样的问题。基于对答案克里斯·约翰逊在这里VonC这里我建立一个简短的bash脚本它迭代通过所有现有gitlink条目,并将它们作为适当的子模块。

#!/bin/bash

# Read all submodules in current git
MODULES=`git ls-files --stage | grep 160000`

# Iterate through every submodule path
while read -r MOD; do
  # extract submodule path (split line at whitespace and take string with index 3)
  ARRIN=(${MOD})
  MODPATH=${ARRIN[3]}

  # grep module url from .git file in submodule path
  MODURL=`grep "url = " $MODPATH/.git/config`
  MODURL=${MODURL##*=}

  # echo path and url for information
  echo $MODPATH
  echo $MODURL

  # remove existing entry in submodule index
  git rm --cached $MODPATH
  # add new entry in submodule index
  git submodule add $MODURL $MODPATH
done <<< "$MODULES"

This fixed it for me, I hope it is of any help.

这为我修复了它,我希望它有任何帮助。

回答by rmk

http://progit.org/book/ch6-6.html

http://progit.org/book/ch6-6.html

I think you should read this to learn a little about submodule. It's well-written, and it doesn't take much time to read it.

我认为您应该阅读本文以了解有关子模块的一些知识。写的很好,不用花太多时间读完。

回答by DarkCrazy

This worked out just fine for me:

这对我来说很好:

git update-index --skip-worktree

git update-index --skip-worktree

If it doesn't work with the pathname, try the filename. Let me know if this worked for you too.

如果路径名不起作用,请尝试文件名。让我知道这是否也适合您。

Bye!

再见!

回答by Dana Scheider

This question has been answered already, but thought I'd add to the mix what I found out when I got these messages.

这个问题已经得到了回答,但我想我会在收到这些消息时添加我发现的内容。

I have a repo called playgroundthat contains a number of sandbox apps. I added two new apps from a tutorial to the playgrounddirectory by cloning the tutorial's repo. The result was that the new apps' git stuff pointed to the tutorial's repo and not to my repo. The solution was to delete the .gitdirectory from each of those apps' directories, mvthe apps' directories outside the playgrounddirectory, and then mvthem back and run git add .. After that it worked.

我有一个名为的 repo playground,其中包含许多沙盒应用程序。我playground通过克隆教程的存储库将教程中的两个新应用程序添加到目录中。结果是新应用程序的 git 内容指向教程的仓库而不是我的仓库。解决方案是.git从每个应用程序的目录中删除目录,mv目录外的应用程序playground目录,然后mv它们返回并运行git add .. 在那之后它起作用了。

回答by nero

Had the same problem, but it was not solved in this discussion.

有同样的问题,但在这次讨论中没有解决。

I hit also the submodule problem as described in the thread opening.

我也遇到了线程开头中描述的子模块问题。

% git status          
# On branch master
# Changes not staged for commit:
#   modified:   bundle/taglist (untracked content)

Looking at the diff I recognized a -dirty appended to a hash: Reading the docs again, solved the problem for me. http://web.mit.edu/jhawk/mnt/spo/git/git-doc/user-manual.htmlLook at section "Pitfalls with submodules"

查看差异,我识别出附加到哈希的 -dirty:再次阅读文档,为我解决了问题。 http://web.mit.edu/jhawk/mnt/spo/git/git-doc/user-manual.html查看“子模块的陷阱”部分

Reason was, there were changes or untracked content within the submodule. I first had to got to the submodule directory, do a "git add" + "git commit" to get all content tracked within the submodule.

原因是,子模块中有更改或未跟踪的内容。我首先必须进入子模块目录,执行“git add”+“git commit”以获取子模块中跟踪的所有内容。

Then "git status" on the master stated
% git commit
# On branch master
# Changes not staged for commit:
#   modified:   bundle/taglist (new commits)

Now this new HEAD from the submodule could be commited to the master module.

现在这个来自子模块的新 HEAD 可以提交到主模块。