Incorporated suggestions into git page and edit for more brevity.
The Advanced Rebasing section has been mostly rewritten to include both a major suggestion from jyn and a general rewrite. Additional thanks to camelid for some suggestions!
This commit is contained in:
parent
fb23f10071
commit
7f590fa025
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
- [Introduction](./contributing.md)
|
- [Introduction](./contributing.md)
|
||||||
- [About the compiler team](./compiler-team.md)
|
- [About the compiler team](./compiler-team.md)
|
||||||
- [Using git](./git.md)
|
- [Using Git](./git.md)
|
||||||
- [Mastering @rustbot](./rustbot.md)
|
- [Mastering @rustbot](./rustbot.md)
|
||||||
- [Walkthrough: a typical contribution](./walkthrough.md)
|
- [Walkthrough: a typical contribution](./walkthrough.md)
|
||||||
- [Bug Fix Procedure](./bug-fix-procedure.md)
|
- [Bug Fix Procedure](./bug-fix-procedure.md)
|
||||||
|
|
|
||||||
95
src/git.md
95
src/git.md
|
|
@ -1,29 +1,29 @@
|
||||||
# Using git
|
# Using Git
|
||||||
|
|
||||||
The Rust project uses [git] to manage its source code. In order to
|
The Rust project uses [Git] to manage its source code. In order to
|
||||||
contribute, you'll need some familiarity with its features so that your changes
|
contribute, you'll need some familiarity with its features so that your changes
|
||||||
can be incorporated into the compiler.
|
can be incorporated into the compiler.
|
||||||
|
|
||||||
[git]: https://git-scm.com
|
[Git]: https://git-scm.com
|
||||||
|
|
||||||
The goal of this page is to cover some of the more common questions and
|
The goal of this page is to cover some of the more common questions and
|
||||||
problems new contributors face. Although some git basics will be covered here,
|
problems new contributors face. Although some Git basics will be covered here,
|
||||||
if you find that this is still a little too fast for you, it might make sense
|
if you find that this is still a little too fast for you, it might make sense
|
||||||
to first read some introductions to git, such as the Beginner and Getting
|
to first read some introductions to Git, such as the Beginner and Getting
|
||||||
started sections of [this tutorial from Atlassian][atlassian-git]. GitHub also
|
started sections of [this tutorial from Atlassian][atlassian-git]. GitHub also
|
||||||
provides [documentation] and [guides] for beginners, or you can consult the
|
provides [documentation] and [guides] for beginners, or you can consult the
|
||||||
more in depth [book from git].
|
more in depth [book from Git].
|
||||||
|
|
||||||
[book from git]: https://git-scm.com/book/en/v2/
|
[book from Git]: https://git-scm.com/book/en/v2/
|
||||||
[atlassian-git]: https://www.atlassian.com/git/tutorials/what-is-version-control
|
[atlassian-git]: https://www.atlassian.com/git/tutorials/what-is-version-control
|
||||||
[documentation]: https://docs.github.com/en/github/getting-started-with-github/set-up-git
|
[documentation]: https://docs.github.com/en/github/getting-started-with-github/set-up-git
|
||||||
[guides]: https://guides.github.com/introduction/git-handbook/
|
[guides]: https://guides.github.com/introduction/git-handbook/
|
||||||
|
|
||||||
## Prequisites
|
## Prequisites
|
||||||
|
|
||||||
We'll assume that you've installed git, forked [rust-lang/rust], and cloned the
|
We'll assume that you've installed Git, forked [rust-lang/rust], and cloned the
|
||||||
forked repo to your PC. We'll use the command line interface to interact
|
forked repo to your PC. We'll use the command line interface to interact
|
||||||
with git; there are also a number of GUIs and IDE integrations that can
|
with Git; there are also a number of GUIs and IDE integrations that can
|
||||||
generally do the same things.
|
generally do the same things.
|
||||||
|
|
||||||
[rust-lang/rust]: https://github.com/rust-lang/rust
|
[rust-lang/rust]: https://github.com/rust-lang/rust
|
||||||
|
|
@ -33,13 +33,13 @@ in your local repo. It may be helpful to also set up a remote for the official
|
||||||
rust-lang/rust repo via
|
rust-lang/rust repo via
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git remote add rust https://github.com/rust-lang/rust.git
|
git remote add upstream https://github.com/rust-lang/rust.git
|
||||||
```
|
```
|
||||||
|
|
||||||
if you're using HTTPS, or
|
if you're using HTTPS, or
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git remote add rust git@github.com:rust-lang/rust.git
|
git remote add upstream git@github.com:rust-lang/rust.git
|
||||||
```
|
```
|
||||||
|
|
||||||
if you're using SSH.
|
if you're using SSH.
|
||||||
|
|
@ -51,7 +51,7 @@ and PRs:
|
||||||
|
|
||||||
1. Ensure that you're making your changes on top of master:
|
1. Ensure that you're making your changes on top of master:
|
||||||
`git checkout master`.
|
`git checkout master`.
|
||||||
2. Get the latest changes from the Rust repo: `git pull rust master`.
|
2. Get the latest changes from the Rust repo: `git pull upstream master`.
|
||||||
3. Make a new branch for your change: `git checkout -b issue-12345-fix`.
|
3. Make a new branch for your change: `git checkout -b issue-12345-fix`.
|
||||||
4. Make some changes to the repo and test them.
|
4. Make some changes to the repo and test them.
|
||||||
5. Stage your changes via `git add src/changed/file.rs src/another/change.rs`
|
5. Stage your changes via `git add src/changed/file.rs src/another/change.rs`
|
||||||
|
|
@ -60,7 +60,7 @@ and PRs:
|
||||||
unintentionally commit changes that should not be committed, such as submodule
|
unintentionally commit changes that should not be committed, such as submodule
|
||||||
updates. You can use `git status` to check if there are any files you forgot
|
updates. You can use `git status` to check if there are any files you forgot
|
||||||
to stage.
|
to stage.
|
||||||
6. Push your changes to your fork: `git push -u origin issue-12345-fix`.
|
6. Push your changes to your fork: `git push --set-upstream origin issue-12345-fix`.
|
||||||
7. [Open a PR][ghpullrequest] from your fork to rust-lang/rust's master branch.
|
7. [Open a PR][ghpullrequest] from your fork to rust-lang/rust's master branch.
|
||||||
|
|
||||||
[ghpullrequest]: https://guides.github.com/activities/forking/#making-a-pull-request
|
[ghpullrequest]: https://guides.github.com/activities/forking/#making-a-pull-request
|
||||||
|
|
@ -82,19 +82,19 @@ to rust-lang/rust since then are in conflict with the changes you've made.
|
||||||
|
|
||||||
When this happens, you need to resolve the conflicts before your changes can be
|
When this happens, you need to resolve the conflicts before your changes can be
|
||||||
merged. First, get a local copy of the conflicting changes: Checkout your local
|
merged. First, get a local copy of the conflicting changes: Checkout your local
|
||||||
master branch with `git checkout master`, then `git pull rust master` to
|
master branch with `git checkout master`, then `git pull upstream master` to
|
||||||
update it with the most recent changes.
|
update it with the most recent changes.
|
||||||
|
|
||||||
### Rebasing
|
### Rebasing
|
||||||
|
|
||||||
You're now ready to start the rebasing process. Check out the branch with your
|
You're now ready to start the rebasing process. Checkout the branch with your
|
||||||
changes and execute `git rebase master`.
|
changes and execute `git rebase master`.
|
||||||
|
|
||||||
When you rebase a branch on master, all the changes on your branch are
|
When you rebase a branch on master, all the changes on your branch are
|
||||||
reapplied to the most recent version of master. In other words, git tries to
|
reapplied to the most recent version of master. In other words, Git tries to
|
||||||
pretend that the changes you made to the old version of master were instead
|
pretend that the changes you made to the old version of master were instead
|
||||||
made to the new version of master. During this process, you should expect to
|
made to the new version of master. During this process, you should expect to
|
||||||
encounter at least one "rebase conflict." This happens when git's attempt to
|
encounter at least one "rebase conflict." This happens when Git's attempt to
|
||||||
reapply the changes fails because your changes conflicted with other changes
|
reapply the changes fails because your changes conflicted with other changes
|
||||||
that have been made. You can tell that this happened because you'll see
|
that have been made. You can tell that this happened because you'll see
|
||||||
lines in the output that look like
|
lines in the output that look like
|
||||||
|
|
@ -113,24 +113,24 @@ Your code
|
||||||
>>>>>>> 8fbf656... Commit fixes 12345
|
>>>>>>> 8fbf656... Commit fixes 12345
|
||||||
```
|
```
|
||||||
|
|
||||||
This represents the lines in the file that git could not figure out how to
|
This represents the lines in the file that Git could not figure out how to
|
||||||
rebase. The section between `<<<<<<< HEAD` and `=======` has the code from
|
rebase. The section between `<<<<<<< HEAD` and `=======` has the code from
|
||||||
master, while the other side has your version of the code. You'll need to
|
master, while the other side has your version of the code. You'll need to
|
||||||
decide how to deal with the conflict. You may want to keep your changes,
|
decide how to deal with the conflict. You may want to keep your changes,
|
||||||
keep the changes on master, or combine the two.
|
keep the changes on master, or combine the two.
|
||||||
|
|
||||||
Generally, resovling the conflict consists of two steps: First, fix the
|
Generally, resolving the conflict consists of two steps: First, fix the
|
||||||
particular conflict. Edit the file to make the changes you want and remove the
|
particular conflict. Edit the file to make the changes you want and remove the
|
||||||
`<<<<<<<`, `=======` and `>>>>>>>` lines in the process. Second, check the
|
`<<<<<<<`, `=======` and `>>>>>>>` lines in the process. Second, check the
|
||||||
surrounding code. If there was a conflict, its because someone else changed the
|
surrounding code. If there was a conflict, its likely there are some logical
|
||||||
same code you did. That means its likely there are some logical errors lying
|
errors lying around too! It's a good idea to run `x.py check` here to make sure
|
||||||
around too!
|
there are no glaring errors.
|
||||||
|
|
||||||
Once you're all done fixing the conflicts, you need to stage the files that had
|
Once you're all done fixing the conflicts, you need to stage the files that had
|
||||||
conflicts in them via `git add`. Afterwards, run `git rebase --continue` to let
|
conflicts in them via `git add`. Afterwards, run `git rebase --continue` to let
|
||||||
git know that you've resolved the conflicts and it should finish the rebase.
|
Git know that you've resolved the conflicts and it should finish the rebase.
|
||||||
Once the rebase has succeeded, you'll want to update the associated branch on
|
Once the rebase has succeeded, you'll want to update the associated branch on
|
||||||
your fork with `git push -f`.
|
your fork with `git push --force-with-lease`.
|
||||||
|
|
||||||
Note that `git push` will not work properly and say something like this:
|
Note that `git push` will not work properly and say something like this:
|
||||||
|
|
||||||
|
|
@ -143,32 +143,37 @@ hint: 'git pull ...') before pushing again.
|
||||||
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
|
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
|
||||||
```
|
```
|
||||||
|
|
||||||
The advice this gives is incorrect! Because of the "no-merge" policy, running
|
The advice this gives is incorrect! Because of Rust's
|
||||||
`git pull` will create a merge commit, defeating the point of your rebase. Use
|
["no-merge" policy](#no-merge-policy) the merge commit created by `git pull`
|
||||||
`git push -f` instead.
|
will not be allowed in the final PR, in addition to defeating the point of the
|
||||||
|
rebase! Use `git push --force-with-lease` instead.
|
||||||
|
|
||||||
## Advanced Rebasing
|
## Advanced Rebasing
|
||||||
|
|
||||||
Sometimes, you may want to perform a more complicated rebase. There are two
|
|
||||||
common scenarios that might call for this.
|
|
||||||
|
|
||||||
If your branch contains multiple consecutive rewrites of the same code, or if
|
If your branch contains multiple consecutive rewrites of the same code, or if
|
||||||
the rebase conflicts are extremely severe, it is possible that just trying to
|
the rebase conflicts are extremely severe, you can use
|
||||||
reapply the changes you made on top of the updated code will be too much of a
|
`git rebase --interactive master` to gain more control over the process. This
|
||||||
headache. In this case, you can use the interactive rebase feature via
|
allows you to choose to skip commits, edit the commits that you do not skip,
|
||||||
`git rebase -i master` to gain more control over the process. This allows you
|
change the order in which they are applied, or "squash" them into each other.
|
||||||
to choose to skip commits because they represent changes you no longer need,
|
|
||||||
edit the commits that you do not skip, or change the order in which they are
|
|
||||||
applied.
|
|
||||||
|
|
||||||
The other common scenario is if you are asked to or want to "squash" multiple
|
Alternatively, you can sacrifice the commit history like this:
|
||||||
commits into each other. If you PR needs only a minor revision, a single commit
|
|
||||||
at the end with message "fixup small issue" is usually unhelpful, and it is
|
```
|
||||||
easier for everyone if you combine that commit with another that has a more
|
# squash all the changes into one commit so you only have to worry about conflicts once
|
||||||
meaningful commit message. Run `git rebase -i HEAD~2` to edit the last two
|
git rebase -i $(git merge-base master) # and squash all changes along the way
|
||||||
commits so you can merge them together. By selecting the `-i` option, you give
|
git rebase master
|
||||||
yourself the opportunity to edit the rebase, similarly to above. This way you
|
# fix all merge conflicts
|
||||||
can request to have the most recent commit squashed into its parent.
|
git rebase --continue
|
||||||
|
```
|
||||||
|
|
||||||
|
"Squashing" commits into each other causes them to be merged into a single
|
||||||
|
commit. Both the upside and downside of this is that it simplifies the history.
|
||||||
|
On the one hand, you lose track of the steps in which changes were made, but
|
||||||
|
the history becomes easier to work with.
|
||||||
|
|
||||||
|
You also may want to squash just the last few commits together, possibly
|
||||||
|
because they only represent "fixups" and not real changes. For example,
|
||||||
|
`git rebase --interactive HEAD~2` will allow you to edit the two commits only.
|
||||||
|
|
||||||
## No-Merge Policy
|
## No-Merge Policy
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue