Home Explore Blog CI



rustc

12th chunk of `src/git.md`
7dd91486f312e6f56db194ee66dfa2fef74f6f6c88cf06ff0000000100000e69
This is because, like any dependency, we want to be able to control which version to use.
Submodules allow us to do just that: every submodule is "pinned" to a certain
commit, which doesn't change unless modified manually. If you use `git checkout <commit>`
in the `llvm-project` directory and go back to the `rust` directory, you can stage this
change like any other, e.g. by running `git add src/llvm-project`. (Note that if
you *don't* stage the change to commit, then you run the risk that running
`x` will just undo your change by switching back to the previous commit when
it automatically "updates" the submodules.)

This version selection is usually done by the maintainers of the project, and
looks like [this][llvm-update].

Git submodules take some time to get used to, so don't worry if it isn't perfectly
clear yet. You will rarely have to use them directly and, again, you don't need
to know everything about submodules to contribute to Rust. Just know that they
exist and that they correspond to some sort of embedded subrepository dependency
that Git can nicely and fairly conveniently handle for us.

### Hard-resetting submodules

Sometimes you might run into (when you run `git status`)

```console
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)
        modified:   src/llvm-project (new commits, modified content)
```

and when you try to run `git submodule update` it breaks horribly with errors like

```console
error: RPC failed; curl 92 HTTP/2 stream 7 was not closed cleanly: CANCEL (err 8)
error: 2782 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
fatal: Fetched in submodule path 'src/llvm-project', but it did not contain 5a5152f653959d14d68613a3a8a033fb65eec021. Direct fetching of that commit failed.
```

If you see `(new commits, modified content)` you can run

```console
git submodule foreach git reset --hard
```

and then try `git submodule update` again.

### Deinit git submodules

If that doesn't work, you can try to deinit all git submodules...

```console
git submodule deinit -f --all
```

Unfortunately sometimes your local git submodules configuration can become
completely messed up for some reason.

### Overcoming `fatal: not a git repository: <submodule>/../../.git/modules/<submodule>`

Sometimes, for some forsaken reason, you might run into

```console
fatal: not a git repository: src/gcc/../../.git/modules/src/gcc
```

In this situation, for the given submodule path, i.e. `<submodule_path> =
src/gcc` in this example, you need to:

1. `rm -rf <submodule_path>/.git`
2. `rm -rf .git/modules/<submodule_path>/config`
3. `rm -rf .gitconfig.lock` if somehow the `.gitconfig` lock is orphaned.

Then do something like `./x fmt` to have bootstrap manage the submodule
checkouts for you.

## Ignoring commits during `git blame`

Some commits contain large reformatting changes that don't otherwise change functionality. They can
be instructed to be ignored by `git blame` through
[`.git-blame-ignore-revs`](https://github.com/rust-lang/rust/blob/master/.git-blame-ignore-revs):

1. Configure `git blame` to use `.git-blame-ignore-revs` as the list of commits to ignore: `git
   config blame.ignorerevsfile .git-blame-ignore-revs`
2. Add suitable commits that you wish to be ignored by `git blame`.

Please include a comment for the commit that you add to `.git-blame-ignore-revs` so people can
easily figure out *why* a commit is ignored.


Title: Managing and Troubleshooting Git Submodules; Ignoring Commits in `git blame`
Summary
This section elaborates on managing Git submodules, emphasizing version control and the process of pinning submodules to specific commits. It offers guidance on hard-resetting and deinitializing submodules to resolve potential errors, along with steps to overcome the `fatal: not a git repository` error. Additionally, it describes how to configure `git blame` to ignore specific commits, particularly those involving large reformatting changes, by utilizing the `.git-blame-ignore-revs` file.