search

Home  >  Q&A  >  body text

git忽略已经被提交的文件

现在项目的根目录放了 .gitignore 文件,并且git远程仓库的项目根目录已经有了 logs文件夹。

由于每次本地运行项目,都会生成新的log文件,但是我并不想提交logs文件夹里面的内容,所以要在.gitignore写logs的规则。

我尝试过添加以下规则
logs/*.log
logs/
/logs/

但是运行git status的时候,始终能看到modified:logs/xx.log 。

请问是我的规则编写错误,还是我某个地方有理解错误?

高洛峰高洛峰2798 days ago704

reply all(5)I'll reply

  • 阿神

    阿神2017-04-24 16:02:46

    tl;dr: The correct approach should be: git rm --cached logs/xx.log,然后更新 .gitignore 忽略掉目标文件,最后 git commit -m "We really don't want Git to track this anymore!"

    The specific reasons are as follows:

    Although the accepted answer can achieve the (temporary) purpose, it is not the most correct approach. Doing so misunderstands the meaning of git update-index, and the most direct (bad) consequences of doing so are as follows:

    1. All team members must execute: git update-index --assume-unchanged <PATH> on the target file. This is because even if you let Git pretend not to see changes to the target file, the file itself is still in Git's history, so everyone on the team will pull the changes to the target file when fetch. (But in fact, the target file does not want to be recorded by Git at all, rather than pretending not to see it change)

    2. Once someone changes the target file and directly git update-index --assume-unchanged <PATH>push without , then all members who have pulled the latest code must re-execute update-index, otherwise Git will start recording changes to the target file again. This is actually very common. For example, if a member changes the machine or hard disk and re-clone a code base, since the target file is still in the Git history, he/she is likely to forget the update- index.

      Why is this? The answer lies in Git’s
    3. man pages
    :

    First of all, the definition of git update-index

    is:

    Register file contents in the working tree to the index (Register file contents in the workspace to the index area)

    The implicit meaning of this sentence is:

    update-index
    is aimed at the files recorded in the Git database, not those files that need to be ignored.

    Then look at a few related descriptions about --assume-unchanged

    :

    When the "assume unchanged" bit is on, Git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell Git when you change the working tree file. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).

    roughly means:

    After applying this flag, Git stops looking at possible changes to the workspace files, so you must

    manually
    reset the flag so that Git knows you want to resume tracking file changes. This can be useful when you're working on a large project when the file system's

    system calls are very laggy.

    We know that Git is not only used for code version management, but many projects in other fields also use Git. For example, one of our company's client's projects involved version management of precision parts drawing documents, and they also used Git. One usage scenario is to modify some large files, but every time Git saves it, it must calculate the changes in the file and update the workspace. This delay is very obvious when the hard disk is slow.

    The real usage of

    git update-index --assume-unchanged is this:

    1. You are modifying a huge file, you git update-index --assume-unchanged it first, so that Git will temporarily ignore your modifications to the file;
    2. When your work is finished and ready to be submitted, reset the change logo: git update-index --no-assume-unchanged, so Git only needs to update it once, which is completely acceptable;
    3. Submit + push.

    Also, according to further description in the documentation:

    This option can be also used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files).

    This description tells us two facts:

    1. Although it can be used to achieve the result the poster wants, this is an uncouth approach (coarse);
    2. The same thing should be achieved using .gitignore files (for untracked files).

    The question that arises is: Why did I add the rules in .gitignore but it had no effect?

    This is because we misunderstood the purpose of the .gitignore file. This file can only be used on Untracked Files, that is, files that have never been recorded by Git (since added, they have never been added or committed) document).

    The reason why your rule does not take effect is because those .log files have been recorded by Git, so .log 文件曾经被 Git 记录过,因此 .gitignore is completely invalid for them. This is exactly what the short answer at the beginning does:

    1. Remove tracking of the file from the Git database;
    2. Write the corresponding rules into .gitignore to make the ignoring take effect;
    3. Submit + push.

    Only by doing this, all team members will be consistent without side effects, and only by doing this, other team members will not need to do extra work at all to maintain the ignorance of changes to a file.

    One last thing to note, git rm --cached 删除的是追踪状态,而不是物理文件;如果你真的是彻底不想要了,你也可以直接 rm+ignore+submit.

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-24 16:02:46

    For files that have been maintained, even adding gitignore will not help.
    Use the following command:
    git update-index --assume-unchanged logs/*.log
    In this way, the files under logs will not appear every time you submit

    reply
    0
  • 我想大声告诉你

    我想大声告诉你2017-04-24 16:02:46

    Give me a detailed answer yourself
    .gitignore can only ignore files that have not been tracked originally. If some files have been included in version management, modifying .gitignore is invalid.
    The correct approach is to manually set in each cloned warehouse not to check changes to specific files.

    git update-index --assume-unchanged PATH    在PATH处输入要忽略的文件。
    

    In addition, git also provides another exclude method to do the same thing. The difference is that the .gitignore file itself will be submitted to the repository. Used to save public files that need to be excluded. And .git/info/exclude sets here the files that you need to exclude locally. He won't affect anyone else. It will not be submitted to the repository.

    .gitignore also has an interesting little function. An empty .gitignore file can be used as a placeholder. This becomes useful when you need to create an empty log directory for your project. You can create a log directory and place an empty .gitignore file in it. In this way, when you clone this repo, git will automatically create an empty log directory.

    reply
    0
  • 仅有的幸福

    仅有的幸福2017-04-24 16:02:46

    Delete the log file, add ingore, and commit again

    reply
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-04-24 16:02:46

    I found that the answer with the highest votes (n͛i͛g͛h͛t͛i͛r͛e͛) didn’t understand the question at all
    Instead, @FatGhosta’s answer is the correct one

    If you follow the method of n ͛i ͛ g ͛ h ͛ t ͛i ͛ r ͛e ͛ it is just to achieve
    "Remove the file that does not need to be recorded from git while keeping the file locally and ignore it in future commits"
    instead of reaching
    "Ignore when committing already in git Existing file”

    In fact, the scene should be like this. There is a configuration file, such as the link information of the database.
    Everyone’s link information is definitely not the same, but a standard template must be provided to tell how to fill in the link information. Then it needs to be recorded on git. A standard configuration file, and then each person configures a copy of the link information for their own use according to their own specific circumstances, but does not submit the configuration file to the library
    So FatGhosta’s answer is the correct answer to this question

    reply
    0
  • Cancelreply