|
1 |
+ |
# Git Notes
|
|
2 |
+ |
|
|
3 |
+ |
Git has always been able to attach a note to a commit without rewriting it. Almost nobody uses the feature, because no forge renders notes and no clone fetches them. MNW renders them, lets you write them from the browser, and accepts pushes that plain git would reject.
|
|
4 |
+ |
|
|
5 |
+ |
Notes are ordinary git objects living on `refs/notes/*`. Everything MNW knows about a note is in your repository, not in a database only we can read. Clone the repo and the notes come with it.
|
|
6 |
+ |
|
|
7 |
+ |
## Reading Notes
|
|
8 |
+ |
|
|
9 |
+ |
Nothing to set up. If a repository has notes, they appear:
|
|
10 |
+ |
|
|
11 |
+ |
- On the commit page, one panel per namespace, rendered as markdown.
|
|
12 |
+ |
- As a badge on commit log rows, so you can see which commits are annotated.
|
|
13 |
+ |
- On the Notes tab at `/git/username/repo-name/notes`, which lists every namespace with its count and a reverse-chronological feed of annotations.
|
|
14 |
+ |
- On the file and blame views, alongside the commit being shown.
|
|
15 |
+ |
|
|
16 |
+ |
## Fetching Notes Into Your Clone
|
|
17 |
+ |
|
|
18 |
+ |
A clone does not fetch notes, and git offers no way to change that default. Set the refspec once per clone:
|
|
19 |
+ |
|
|
20 |
+ |
```
|
|
21 |
+ |
git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*'
|
|
22 |
+ |
```
|
|
23 |
+ |
|
|
24 |
+ |
Every `git fetch` after that brings notes along. Read them with `git notes show <commit>`, or point git at a namespace other than the default with `git notes --ref=<namespace> show <commit>`.
|
|
25 |
+ |
|
|
26 |
+ |
This one line is most of why notes go unused everywhere. It is printed on the Notes tab of every repository so you never have to remember it.
|
|
27 |
+ |
|
|
28 |
+ |
## Writing Notes From the Browser
|
|
29 |
+ |
|
|
30 |
+ |
Open any commit page in a repository you can push to. Each namespace panel has add, edit and delete controls, and you can create a new namespace by naming one.
|
|
31 |
+ |
|
|
32 |
+ |
Notes written this way are committed as `Your Display Name <username@users.makenot.work>`. Your account email address never enters the repository's object graph, because an address in a public repo is permanent and clonable by anyone who fetches the notes ref.
|
|
33 |
+ |
|
|
34 |
+ |
Write access follows push access: the repository owner and any collaborator with push permission.
|
|
35 |
+ |
|
|
36 |
+ |
## Pushing Notes From Your Machine
|
|
37 |
+ |
|
|
38 |
+ |
Push notes to the inbox ref for the namespace:
|
|
39 |
+ |
|
|
40 |
+ |
```
|
|
41 |
+ |
git push origin refs/notes/commits:refs/mnw/notes-inbox/commits
|
|
42 |
+ |
```
|
|
43 |
+ |
|
|
44 |
+ |
Replace `commits` with your namespace on both sides. The server merges what you pushed into `refs/notes/commits` and reports the merged tip:
|
|
45 |
+ |
|
|
46 |
+ |
```
|
|
47 |
+ |
notes: merged into refs/notes/commits
|
|
48 |
+ |
```
|
|
49 |
+ |
|
|
50 |
+ |
Then fetch to see the result:
|
|
51 |
+ |
|
|
52 |
+ |
```
|
|
53 |
+ |
git fetch origin
|
|
54 |
+ |
```
|
|
55 |
+ |
|
|
56 |
+ |
Use this in place of `git push origin refs/notes/commits`. The plain push works when nobody else has written a note since you last fetched, and fails with a non-fast-forward rejection when somebody has. The inbox never fails, because the ref you are pushing to does not exist on the server: MNW deletes it as soon as it has merged your notes, so every push creates it fresh. There is no rejection to recover from and no case where the inbox is the wrong target, including the first push to a repository with no notes at all.
|
|
57 |
+ |
|
|
58 |
+ |
The merge uses git's `cat_sort_uniq` strategy. When two people annotate the same commit, both notes survive, sorted and deduplicated. Nothing is discarded and nothing is doubled if the same push is processed twice.
|
|
59 |
+ |
|
|
60 |
+ |
If the server does not answer, the push prints:
|
|
61 |
+ |
|
|
62 |
+ |
```
|
|
63 |
+ |
notes: received, merge deferred (the server did not answer)
|
|
64 |
+ |
```
|
|
65 |
+ |
|
|
66 |
+ |
Your notes are safe in the inbox ref and the next push to that namespace merges them.
|
|
67 |
+ |
|
|
68 |
+ |
## Namespaces
|
|
69 |
+ |
|
|
70 |
+ |
The default namespace is `commits`, which is what bare `git notes` uses. Any other name gives you a separate track of annotation on the same commits: `review`, `design`, `deploys`.
|
|
71 |
+ |
|
|
72 |
+ |
Namespace names may contain letters, numbers, hyphens, underscores, dots and slashes, up to 64 characters, and follow git's ref naming rules. A component cannot start with a dot, contain `..`, or end in `.lock`. Note content is capped at 50,000 characters.
|
|
73 |
+ |
|
|
74 |
+ |
`refs/notes/mnw/*` is reserved. It is where MNW writes its own metadata about your commits, and the web editor, the API and pushes all refuse it. Everything outside that prefix is yours.
|
|
75 |
+ |
|
|
76 |
+ |
## Annotating Files
|
|
77 |
+ |
|
|
78 |
+ |
Git notes can annotate any object, not only commits. A note on a blob is a note on one exact version of one file, and MNW shows it on that file's page. Most tools assume commits and quietly find nothing on the rest.
|
|
79 |
+ |
|
|
80 |
+ |
Notes on blobs are read-only in the browser for now. Write them with `git notes --ref=<namespace> add <blob-oid>` and push them the same way as any other note.
|
|
81 |
+ |
|
|
82 |
+ |
## See Also
|
|
83 |
+ |
|
|
84 |
+ |
- [Git Source Browser](./git.md): browsing, cloning, issues and patches
|
|
85 |
+ |
- [Export](./export.md): taking your data with you
|