Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit aedcdcf

Browse files
committedSep 24, 2020
Add a section on using git.
This section addresses the biggest issues that new contributors, especially those with limited familiarity with git, are likely to face. This is still a WIP.
1 parent 4470641 commit aedcdcf

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed
 

Diff for: ‎src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
- [Implementing new features](./implementing_new_features.md)
3838
- [Stability attributes](./stability.md)
3939
- [Stabilizing Features](./stabilization_guide.md)
40+
- [Using git](./git.md)
4041
- [Coding conventions](./conventions.md)
4142
- [Notification groups](notification-groups/about.md)
4243
- [ARM](notification-groups/arm.md)

Diff for: ‎src/git.md

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Using git
2+
3+
The Rust project uses [git][git] to manage its source code. In order to
4+
contribute, you'll need some familiarity with its features so that your changes
5+
can be incorporated into the compiler.
6+
7+
[git]: https://git-scm.com
8+
9+
The goal of this page is to cover some of the more common questions and
10+
problems new contributors face. Although some git basics will be covered here,
11+
if you have never used git or GitHub before you may find that this is still a
12+
little too fast for you. In that case, it would make sense to first read some
13+
introductions to git, such as the Beginner and Getting started sections of
14+
[this tutorial from Atlassian][atlassian-git]. GitHub also provides
15+
documentation and guides for beginners.
16+
17+
[atlassian-git]: https://www.atlassian.com/git/tutorials/what-is-version-control
18+
19+
Although this page should get you to a point where you can start contributing,
20+
learning more git is almost certainly a good use of your time if you want to
21+
keep contributing. There are many tutorials online for those folks that are
22+
newer which combine excellently with man pages and official documentation.
23+
24+
## Prequisites
25+
26+
We'll assume that you've installed git, forked rust-lang/rust, and cloned the
27+
forked repo to your PC. We'll also use the command line interface to interact
28+
with git; there are also a number of GUIs and IDE integrations that can
29+
generally do the same things.
30+
31+
If you've cloned your fork, then you will be able to reference it with `origin`
32+
in your local repo. It may be helpful to also set up a remote for the official
33+
rust-lang/rust repo via
34+
35+
```sh
36+
git remote add rust git@github.com:rust-lang/rust.git
37+
```
38+
39+
if you're using SSH, or
40+
41+
```sh
42+
git remote add rust https://github.com/rust-lang/rust.git
43+
```
44+
45+
if you're using HTTPS.
46+
47+
## Standard Process
48+
49+
Below is the normal procedure that you're likely to use for most minor changes
50+
and PRs:
51+
52+
1. Ensure that you're making your changes on top of master:
53+
`git checkout master`.
54+
2. Get the latest changes from the Rust repo: `git pull rust master`.
55+
3. Make a new branch for your change: `git checkout -b issue-12345-fix`.
56+
4. Make some changes to the repo and test them.
57+
5. Stage your changes via `git add src/changed/file.rs src/another/change.rs`
58+
and then commit them with `git commit`. Of course, making intermediate commits
59+
may be a good idea as well. Avoid `git add .`, as it makes it too easy to
60+
unintentionally commit changes that should not be committed. You can use
61+
`git status` to check if there are any files you forgot to stage.
62+
6. Push your changes to your fork: `git push -u origin issue-12345-fix`.
63+
7. [Open a PR][ghpullrequest] from your fork to rust-lang/rust's master branch.
64+
65+
[ghpullrequest]: https://guides.github.com/activities/forking/#making-a-pull-request
66+
67+
If your reviewer requests changes, the procedure for those changes looks much
68+
the same, with some steps skipped:
69+
70+
1. Ensure that you're making changes to the most recent version of your code:
71+
`git checkout issue-12345-fix`.
72+
2. Make, stage, and commit your additional changes just like before.
73+
3. Push those changes to your fork: `git push`.
74+
75+
## Conflicts
76+
77+
When you edit your code locally, you are making changes to the version of
78+
rust-lang/rust that existed the last time you ran `git pull rust master` on
79+
your master branch. As such, when you submit your PR it is possible that some
80+
of the changes that have been made to rust-lang/rust since then are in conflict
81+
with the changes you've made; maybe someone else changed the same lines of
82+
code, or git cannot figure out how to merge your changes with the others for
83+
another reason.
84+
85+
When this happens, you need to resolve the conflicts before your changes can be
86+
merged. First, get a local copy of the conflicting changes. Checkout your local
87+
master branch with `git checkout master`. Then, `git pull rust master` to
88+
update it with the most recent changes.
89+
90+
### Rebasing
91+
92+
You're now ready to start the rebasing process. Check out the branch with your
93+
changes, and then execute `git rebase master`.
94+
95+
First, a little background: In git, commits are stored as "diffs" which are a
96+
record of all the changes that a commit made to its parent. When you rebase a
97+
branch, all the changes in the commits on that branch are reapplied on the
98+
branch you are rebasing on top of (in this case master). In other words, git
99+
tries to pretend that the changes you made to the old version of master were
100+
instead made to the new version of master.
101+
102+
During rebasing, you should expect to encounter at least one "rebase conflict."
103+
This happens when git's attempt to reapply the changes onto the more recent
104+
version of master fails because your changes conflicted with other changes that
105+
have been made since then. You can tell that this happened because you'll see
106+
lines in the output that look like
107+
108+
```
109+
CONFLICT (content): Merge conflict in file.rs
110+
```
111+
112+
When you open these files, you'll see sections of the form
113+
114+
```
115+
<<<<<<< HEAD
116+
Original code
117+
=======
118+
Your code
119+
>>>>>>> 8fbf656... Commit fixes 12345
120+
```
121+
122+
This represents the lines in the file that git could not figure out how to
123+
rebase. The section between `<<<<<<< HEAD` and `=======` has the code from
124+
master, while the other side has your version of the code. You'll need to
125+
decide how to deal with the conflict. You may want to keep your changes,
126+
keep the changes on master, or combine the two.
127+
128+
Generally, resovling the conflict consists of two steps: First, fix the
129+
particular conflict. Edit the file to make the changes you want and remove the
130+
`<<<<<<<`, `=======` and `>>>>>>>` lines in the process. Second, check the
131+
surrounding code. If there was a conflict, its because someone else changed the
132+
same code you did. That means its likely there are some logical errors lying
133+
around too!
134+
135+
Once you're all done fixing the conflicts, you need to stage the files that had
136+
conflicts in them via `git add`. Afterwards, run `git rebase --continue` to let
137+
git know that you've resolved the conflicts and it should finish the rebase.
138+
Finally, once the rebase has succeeded, you'll want to update the associated
139+
branch on your fork with `git push -f`.
140+
141+
## Advanced Rebasing
142+
143+
Sometimes, you may want to perform a more complicated rebase. There are two
144+
common scenarios that might call for this.
145+
146+
If your branch contains multiple consecutive rewrites of the same code, or if
147+
the rebase conflicts are extremely severe, it is possible that just trying to
148+
reapply the changes you made on top of the updated code will be too much of a
149+
headache. In this case, you can use the interactive rebase feature via
150+
`git rebase -i master` to gain more control over the process. This allows you
151+
to choose to skip commits because they represent changes you no longer need,
152+
edit the commits that you do not skip, or change the order in which they are
153+
applied.
154+
155+
The other common scenario is if you are asked to or want to "squash" multiple
156+
commits into each other. The most common example of this is likely if you
157+
forgot to run `x.py tidy` before committing. Your PR will need to be revised,
158+
but a single commit at the end with message "fixup tidy issue" is usually
159+
unhelpful, and it is easier for everyone else if you combine that commit with
160+
another that has a more meaningful commit message. In this case, you'll want to
161+
run `git rebase -i HEAD~2` to edit the last two commits and merge them
162+
together. Essentially, this reapplies the last two commits on top of your
163+
current branch; this is of course a no-op, since that is where they are
164+
already. However, by selecting the `-i` option, you give yourself the
165+
opportunity to edit the rebase first, just like before. This way you can
166+
request to have the most recent commit squashed into its parent.
167+
168+
## No-Merge Policy
169+
170+
The rust-lang/rust repo uses what is known as a "rebase workflow." This means
171+
that merge commits in PRs are not accepted. As a result, if you are running
172+
`git merge` locally, chances are good that you should be rebasing instead. Of
173+
course, this is not always true; if your merge will just be a fast-forward,
174+
like the merges that `git pull` usually performs, then no merge commit is
175+
created and you have nothing to worry about.
176+
177+
There are a number of reasons for this decision and like all others, it is of
178+
course a tradeoff. The main advantage is the (mostly) linear commit history.
179+
This greatly simplifies bisecting. TODO: There are other advantages to a rebase
180+
workflow, but I would like to focus on the ones that people in the Rust project
181+
consider most relevant, so I'm going to leave this unfinished for now.

0 commit comments

Comments
 (0)
Please sign in to comment.