View Javadoc
1   /*
2    * Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.api;
11  
12  import java.io.IOException;
13  
14  import org.eclipse.jgit.api.errors.GitAPIException;
15  import org.eclipse.jgit.api.errors.JGitInternalException;
16  import org.eclipse.jgit.lib.CommitBuilder;
17  import org.eclipse.jgit.lib.Constants;
18  import org.eclipse.jgit.lib.ObjectId;
19  import org.eclipse.jgit.lib.ObjectInserter;
20  import org.eclipse.jgit.lib.PersonIdent;
21  import org.eclipse.jgit.lib.Ref;
22  import org.eclipse.jgit.lib.RefUpdate;
23  import org.eclipse.jgit.lib.Repository;
24  import org.eclipse.jgit.notes.Note;
25  import org.eclipse.jgit.notes.NoteMap;
26  import org.eclipse.jgit.revwalk.RevCommit;
27  import org.eclipse.jgit.revwalk.RevObject;
28  import org.eclipse.jgit.revwalk.RevWalk;
29  
30  /**
31   * Add object notes.
32   *
33   * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-notes.html"
34   *      >Git documentation about Notes</a>
35   */
36  public class AddNoteCommand extends GitCommand<Note> {
37  
38  	private RevObject id;
39  
40  	private String message;
41  
42  	private String notesRef = Constants.R_NOTES_COMMITS;
43  
44  	/**
45  	 * Constructor for AddNoteCommand
46  	 *
47  	 * @param repo
48  	 *            the {@link org.eclipse.jgit.lib.Repository}
49  	 */
50  	protected AddNoteCommand(Repository repo) {
51  		super(repo);
52  	}
53  
54  	/** {@inheritDoc} */
55  	@Override
56  	public Note call() throws GitAPIException {
57  		checkCallable();
58  		NoteMap map = NoteMap.newEmptyMap();
59  		RevCommit notesCommit = null;
60  		try (RevWalk walk = new RevWalk(repo);
61  				ObjectInserter inserter = repo.newObjectInserter()) {
62  			Ref ref = repo.findRef(notesRef);
63  			// if we have a notes ref, use it
64  			if (ref != null) {
65  				notesCommit = walk.parseCommit(ref.getObjectId());
66  				map = NoteMap.read(walk.getObjectReader(), notesCommit);
67  			}
68  			map.set(id, message, inserter);
69  			commitNoteMap(repo, notesRef, walk, map, notesCommit, inserter,
70  					"Notes added by 'git notes add'"); //$NON-NLS-1$
71  			return map.getNote(id);
72  		} catch (IOException e) {
73  			throw new JGitInternalException(e.getMessage(), e);
74  		}
75  	}
76  
77  	/**
78  	 * Sets the object id of object you want a note on. If the object already
79  	 * has a note, the existing note will be replaced.
80  	 *
81  	 * @param id
82  	 *            a {@link org.eclipse.jgit.revwalk.RevObject}
83  	 * @return {@code this}
84  	 */
85  	public AddNoteCommand setObjectId(RevObject id) {
86  		checkCallable();
87  		this.id = id;
88  		return this;
89  	}
90  
91  	/**
92  	 * Set the notes message
93  	 *
94  	 * @param message
95  	 *            the notes message used when adding a note
96  	 * @return {@code this}
97  	 */
98  	public AddNoteCommand setMessage(String message) {
99  		checkCallable();
100 		this.message = message;
101 		return this;
102 	}
103 
104 	static void commitNoteMap(Repository r, String ref, RevWalk walk,
105 			NoteMap map,
106 			RevCommit notesCommit,
107 			ObjectInserter inserter,
108 			String msg)
109 			throws IOException {
110 		// commit the note
111 		CommitBuilder builder = new CommitBuilder();
112 		builder.setTreeId(map.writeTree(inserter));
113 		builder.setAuthor(new PersonIdent(r));
114 		builder.setCommitter(builder.getAuthor());
115 		builder.setMessage(msg);
116 		if (notesCommit != null)
117 			builder.setParentIds(notesCommit);
118 		ObjectId commit = inserter.insert(builder);
119 		inserter.flush();
120 		RefUpdate refUpdate = r.updateRef(ref);
121 		if (notesCommit != null)
122 			refUpdate.setExpectedOldObjectId(notesCommit);
123 		else
124 			refUpdate.setExpectedOldObjectId(ObjectId.zeroId());
125 		refUpdate.setNewObjectId(commit);
126 		refUpdate.update(walk);
127 	}
128 
129 	/**
130 	 * Set name of a {@code Ref} to read notes from
131 	 *
132 	 * @param notesRef
133 	 *            the ref to read notes from. Note, the default value of
134 	 *            {@link org.eclipse.jgit.lib.Constants#R_NOTES_COMMITS} will be
135 	 *            used if nothing is set
136 	 * @return {@code this}
137 	 * @see Constants#R_NOTES_COMMITS
138 	 */
139 	public AddNoteCommand setNotesRef(String notesRef) {
140 		checkCallable();
141 		this.notesRef = notesRef;
142 		return this;
143 	}
144 
145 }