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)
|
||||
- [About the compiler team](./compiler-team.md)
|
||||
- [Using git](./git.md)
|
||||
- [Using Git](./git.md)
|
||||
- [Mastering @rustbot](./rustbot.md)
|
||||
- [Walkthrough: a typical contribution](./walkthrough.md)
|
||||
- [Bug Fix Procedure](./bug-fix-procedure.md)
|
||||
|
|
|
|||
93
src/git.md
93
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
[documentation]: https://docs.github.com/en/github/getting-started-with-github/set-up-git
|
||||
[guides]: https://guides.github.com/introduction/git-handbook/
|
||||
|
||||
## 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
|
||||
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.
|
||||
|
||||
[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
|
||||
|
||||
```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
|
||||
|
||||
```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.
|
||||
|
|
@ -51,7 +51,7 @@ and PRs:
|
|||
|
||||
1. Ensure that you're making your changes on top of 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`.
|
||||
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`
|
||||
|
|
@ -60,7 +60,7 @@ and PRs:
|
|||
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
|
||||
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.
|
||||
|
||||
[ghpullrequest]: https://guides.github.com/activities/forking/#making-a-pull-request
|
||||
|
|
@ -82,7 +82,7 @@ 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
|
||||
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.
|
||||
|
||||
### Rebasing
|
||||
|
|
@ -91,10 +91,10 @@ You're now ready to start the rebasing process. Check out the branch with your
|
|||
changes and execute `git rebase master`.
|
||||
|
||||
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
|
||||
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
|
||||
that have been made. You can tell that this happened because you'll see
|
||||
lines in the output that look like
|
||||
|
|
@ -113,24 +113,24 @@ Your code
|
|||
>>>>>>> 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
|
||||
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,
|
||||
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
|
||||
`<<<<<<<`, `=======` and `>>>>>>>` lines in the process. Second, check the
|
||||
surrounding code. If there was a conflict, its because someone else changed the
|
||||
same code you did. That means its likely there are some logical errors lying
|
||||
around too!
|
||||
surrounding code. If there was a conflict, its likely there are some logical
|
||||
errors lying around too! It's a good idea to run `x.py check` here to make sure
|
||||
there are no glaring errors.
|
||||
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
|
|
@ -143,32 +143,37 @@ hint: 'git pull ...') before pushing again.
|
|||
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
|
||||
`git pull` will create a merge commit, defeating the point of your rebase. Use
|
||||
`git push -f` instead.
|
||||
The advice this gives is incorrect! Because of Rust's
|
||||
["no-merge" policy](#no-merge-policy) the merge commit created by `git pull`
|
||||
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
|
||||
|
||||
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
|
||||
the rebase conflicts are extremely severe, it is possible that just trying to
|
||||
reapply the changes you made on top of the updated code will be too much of a
|
||||
headache. In this case, you can use the interactive rebase feature via
|
||||
`git rebase -i master` to gain more control over the process. This allows you
|
||||
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 rebase conflicts are extremely severe, you can use
|
||||
`git rebase --interactive master` to gain more control over the process. This
|
||||
allows you to choose to skip commits, edit the commits that you do not skip,
|
||||
change the order in which they are applied, or "squash" them into each other.
|
||||
|
||||
The other common scenario is if you are asked to or want to "squash" multiple
|
||||
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
|
||||
meaningful commit message. Run `git rebase -i HEAD~2` to edit the last two
|
||||
commits so you can merge them together. By selecting the `-i` option, you give
|
||||
yourself the opportunity to edit the rebase, similarly to above. This way you
|
||||
can request to have the most recent commit squashed into its parent.
|
||||
Alternatively, you can sacrifice the commit history like this:
|
||||
|
||||
```
|
||||
# squash all the changes into one commit so you only have to worry about conflicts once
|
||||
git rebase -i $(git merge-base master) # and squash all changes along the way
|
||||
git rebase master
|
||||
# fix all merge conflicts
|
||||
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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue