下面列出了怎么用org.eclipse.jgit.transport.TrackingRefUpdate的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public RevWalk fetchAndCreateNewRevsWalk(Repository repository, String branch) throws Exception {
List<ObjectId> currentRemoteRefs = new ArrayList<ObjectId>();
for (Ref ref : repository.getAllRefs().values()) {
String refName = ref.getName();
if (refName.startsWith(REMOTE_REFS_PREFIX)) {
currentRemoteRefs.add(ref.getObjectId());
}
}
List<TrackingRefUpdate> newRemoteRefs = this.fetch(repository);
RevWalk walk = new RevWalk(repository);
for (TrackingRefUpdate newRef : newRemoteRefs) {
if (branch == null || newRef.getLocalName().endsWith("/" + branch)) {
walk.markStart(walk.parseCommit(newRef.getNewObjectId()));
}
}
for (ObjectId oldRef : currentRemoteRefs) {
walk.markUninteresting(walk.parseCommit(oldRef));
}
walk.setRevFilter(commitsFilter);
return walk;
}
private List<TrackingRefUpdate> fetch(Repository repository) throws Exception {
this.logger.info("Fetching changes of repository " + repository.getDirectory().toString());
try (Git git = new Git(repository)) {
FetchResult result = git.fetch().call();
Collection<TrackingRefUpdate> updates = result.getTrackingRefUpdates();
List<TrackingRefUpdate> remoteRefsChanges = new ArrayList<TrackingRefUpdate>();
for (TrackingRefUpdate update : updates) {
String refName = update.getLocalName();
if (refName.startsWith(REMOTE_REFS_PREFIX)) {
ObjectId newObjectId = update.getNewObjectId();
this.logger.info(refName +" is now at " + newObjectId.getName());
remoteRefsChanges.add(update);
}
}
if (updates.isEmpty()) {
this.logger.info("Nothing changed");
}
return remoteRefsChanges;
}
}
static IStatus handleFetchResult(FetchResult fetchResult) {
// handle result
for (TrackingRefUpdate updateRes : fetchResult.getTrackingRefUpdates()) {
Result res = updateRes.getResult();
switch (res) {
case NOT_ATTEMPTED:
case NO_CHANGE:
case NEW:
case FORCED:
case FAST_FORWARD:
case RENAMED:
// do nothing, as these statuses are OK
break;
case REJECTED:
return new Status(IStatus.WARNING, GitActivator.PI_GIT, "Fetch rejected, not a fast-forward.");
case REJECTED_CURRENT_BRANCH:
return new Status(IStatus.WARNING, GitActivator.PI_GIT, "Rejected because trying to delete the current branch.");
default:
return new Status(IStatus.ERROR, GitActivator.PI_GIT, res.name());
}
}
return Status.OK_STATUS;
}
private List<TrackingRefUpdate> fetch(Repository repository) throws Exception {
logger.info("Fetching changes of repository {}", repository.getDirectory().toString());
try (Git git = new Git(repository)) {
FetchResult result = git.fetch().call();
Collection<TrackingRefUpdate> updates = result.getTrackingRefUpdates();
List<TrackingRefUpdate> remoteRefsChanges = new ArrayList<TrackingRefUpdate>();
for (TrackingRefUpdate update : updates) {
String refName = update.getLocalName();
if (refName.startsWith(REMOTE_REFS_PREFIX)) {
ObjectId newObjectId = update.getNewObjectId();
logger.info("{} is now at {}", refName, newObjectId.getName());
remoteRefsChanges.add(update);
}
}
if (updates.isEmpty()) {
logger.info("Nothing changed");
}
return remoteRefsChanges;
}
}
public RevWalk fetchAndCreateNewRevsWalk(Repository repository, String branch) throws Exception {
List<ObjectId> currentRemoteRefs = new ArrayList<ObjectId>();
for (Ref ref : repository.getRefDatabase().getRefs()) {
String refName = ref.getName();
if (refName.startsWith(REMOTE_REFS_PREFIX)) {
currentRemoteRefs.add(ref.getObjectId());
}
}
List<TrackingRefUpdate> newRemoteRefs = this.fetch(repository);
RevWalk walk = new RevWalk(repository);
for (TrackingRefUpdate newRef : newRemoteRefs) {
if (branch == null || newRef.getLocalName().endsWith("/" + branch)) {
walk.markStart(walk.parseCommit(newRef.getNewObjectId()));
}
}
for (ObjectId oldRef : currentRemoteRefs) {
walk.markUninteresting(walk.parseCommit(oldRef));
}
walk.setRevFilter(commitsFilter);
return walk;
}
GitTransportUpdate (URIish uri, TrackingRefUpdate update) {
this.localName = stripRefs(update.getLocalName());
this.remoteName = stripRefs(update.getRemoteName());
this.oldObjectId = update.getOldObjectId() == null || ObjectId.zeroId().equals(update.getOldObjectId()) ? null : update.getOldObjectId().getName();
this.newObjectId = update.getNewObjectId() == null || ObjectId.zeroId().equals(update.getNewObjectId()) ? null : update.getNewObjectId().getName();
this.result = GitRefUpdateResult.valueOf((update.getResult() == null
? RefUpdate.Result.NOT_ATTEMPTED
: update.getResult()).name());
this.uri = uri.toString();
this.type = getType(update.getLocalName());
}
/**
* Deletes local branches if corresponding remote branch was removed.
* @param trackingRefUpdates list of tracking ref updates
* @param git git instance
* @return list of deleted branches
*/
private Collection<String> deleteUntrackedLocalBranches(
Collection<TrackingRefUpdate> trackingRefUpdates, Git git) {
if (CollectionUtils.isEmpty(trackingRefUpdates)) {
return Collections.emptyList();
}
Collection<String> branchesToDelete = new ArrayList<>();
for (TrackingRefUpdate trackingRefUpdate : trackingRefUpdates) {
ReceiveCommand receiveCommand = trackingRefUpdate.asReceiveCommand();
if (receiveCommand.getType() == DELETE) {
String localRefName = trackingRefUpdate.getLocalName();
if (StringUtils.startsWithIgnoreCase(localRefName,
LOCAL_BRANCH_REF_PREFIX)) {
String localBranchName = localRefName.substring(
LOCAL_BRANCH_REF_PREFIX.length(), localRefName.length());
branchesToDelete.add(localBranchName);
}
}
}
if (CollectionUtils.isEmpty(branchesToDelete)) {
return Collections.emptyList();
}
try {
// make sure that deleted branch not a current one
checkout(git, this.defaultLabel);
return deleteBranches(git, branchesToDelete);
}
catch (Exception ex) {
String message = format("Failed to delete %s branches.", branchesToDelete);
warn(message, ex);
return Collections.emptyList();
}
}
/**
* Check references updates for any errors
*
* @param errorPrefix The error prefix for any error message
* @param refUpdates A collection of tracking references updates
*/
public static void validateTrackingRefUpdates(String errorPrefix, Collection<TrackingRefUpdate> refUpdates) {
for (TrackingRefUpdate refUpdate : refUpdates) {
RefUpdate.Result result = refUpdate.getResult();
if (result == RefUpdate.Result.IO_FAILURE ||
result == RefUpdate.Result.LOCK_FAILURE ||
result == RefUpdate.Result.REJECTED ||
result == RefUpdate.Result.REJECTED_CURRENT_BRANCH ) {
throw new BuildException(String.format("%s - Status '%s'", errorPrefix, result.name()));
}
}
}
@Override
public GitTransportUpdate createTransportUpdate (URIish urI, TrackingRefUpdate update) {
return new GitTransportUpdate(urI, update);
}
public void testPushRejectNonFastForward () throws Exception {
String remoteUri = getRemoteRepository().getWorkTree().toURI().toString();
assertEquals(0, getClient(workDir).listRemoteBranches(remoteUri, NULL_PROGRESS_MONITOR).size());
File f = new File(workDir, "f");
add(f);
String id = getClient(workDir).commit(new File[] { f }, "bbb", null, null, NULL_PROGRESS_MONITOR).getRevision();
Map<String, GitTransportUpdate> updates = getClient(workDir).push(remoteUri, Arrays.asList(new String[] { "refs/heads/master:refs/heads/master" }), Collections.<String>emptyList(), NULL_PROGRESS_MONITOR).getRemoteRepositoryUpdates();
Map<String, GitBranch> remoteBranches = getClient(workDir).listRemoteBranches(remoteUri, NULL_PROGRESS_MONITOR);
assertEquals(1, remoteBranches.size());
assertEquals(id, remoteBranches.get("master").getId());
assertEquals(1, updates.size());
assertUpdate(updates.get("master"), "master", "master", id, null, new URIish(remoteUri).toString(), Type.BRANCH, GitRefUpdateResult.OK);
// modification
write(f, "huhu");
add(f);
String newid = getClient(workDir).commit(new File[] { f }, "bbb", null, null, NULL_PROGRESS_MONITOR).getRevision();
updates = getClient(workDir).push(remoteUri, Arrays.asList(new String[] { "refs/heads/master:refs/heads/master" }), Collections.<String>emptyList(), NULL_PROGRESS_MONITOR).getRemoteRepositoryUpdates();
remoteBranches = getClient(workDir).listRemoteBranches(remoteUri, NULL_PROGRESS_MONITOR);
assertEquals(1, remoteBranches.size());
assertEquals(newid, remoteBranches.get("master").getId());
assertEquals(1, updates.size());
assertUpdate(updates.get("master"), "master", "master", newid, id, new URIish(remoteUri).toString(), Type.BRANCH, GitRefUpdateResult.OK);
getClient(workDir).createBranch("localbranch", id, NULL_PROGRESS_MONITOR);
getClient(workDir).checkoutRevision("localbranch", true, NULL_PROGRESS_MONITOR);
write(f, "huhu2");
add(f);
id = getClient(workDir).commit(new File[] { f }, "some change before merge", null, null, NULL_PROGRESS_MONITOR).getRevision();
updates = getClient(workDir).push(remoteUri, Arrays.asList(new String[] { "+refs/heads/localbranch:refs/heads/master" }), Collections.<String>emptyList(), NULL_PROGRESS_MONITOR).getRemoteRepositoryUpdates();
remoteBranches = getClient(workDir).listRemoteBranches(remoteUri, NULL_PROGRESS_MONITOR);
assertEquals(1, remoteBranches.size());
assertEquals(newid, remoteBranches.get("master").getId());
assertEquals(1, updates.size());
assertUpdate(updates.get("master"), "localbranch", "master", id, newid, new URIish(remoteUri).toString(), Type.BRANCH, GitRefUpdateResult.REJECTED_NONFASTFORWARD);
updates = getClient(workDir).push(remoteUri, Arrays.asList(new String[] { "refs/heads/localbranch:refs/heads/master" }), Arrays.asList(new String[] { "+refs/heads/master:refs/remotes/origin/master" }), NULL_PROGRESS_MONITOR).getRemoteRepositoryUpdates();
remoteBranches = getClient(workDir).listRemoteBranches(remoteUri, NULL_PROGRESS_MONITOR);
assertEquals(1, remoteBranches.size());
assertEquals(newid, remoteBranches.get("master").getId());
assertEquals(1, updates.size());
assertUpdate(updates.get("master"), "localbranch", "master", id, newid, new URIish(remoteUri).toString(), Type.BRANCH, GitRefUpdateResult.REJECTED_NONFASTFORWARD);
// if starts failing, the WA at GitTransportUpdate.(URIish uri, TrackingRefUpdate update) should be removed
// this.result = GitRefUpdateResult.valueOf((update.getResult() == null ? RefUpdate.Result.NOT_ATTEMPTED : update.getResult()).name());
Transport transport = Transport.open(getRepository(getClient(workDir)), new URIish(remoteUri));
transport.setDryRun(false);
transport.setPushThin(true);
PushResult pushResult = transport.push(new DelegatingProgressMonitor(NULL_PROGRESS_MONITOR),
Transport.findRemoteRefUpdatesFor(getRepository(getClient(workDir)),
Collections.singletonList(new RefSpec("refs/heads/localbranch:refs/heads/master")),
Collections.singletonList(new RefSpec("refs/heads/master:refs/remotes/origin/master"))));
assertEquals(1, pushResult.getTrackingRefUpdates().size());
for (TrackingRefUpdate update : pushResult.getTrackingRefUpdates()) {
// null but not NOT_ATTEMPTED, probably a bug
// remove the WA if it starts failing here
assertNull(update.getResult());
}
}
private IStatus doPush(IProgressMonitor monitor) throws IOException, CoreException, URISyntaxException, GitAPIException {
ProgressMonitor gitMonitor = new EclipseGitProgressTransformer(monitor);
// /git/remote/{remote}/{branch}/file/{path}
File gitDir = GitUtils.getGitDir(path.removeFirstSegments(2));
Repository db = null;
JSONObject result = new JSONObject();
try {
db = FileRepositoryBuilder.create(gitDir);
Git git = Git.wrap(db);
PushCommand pushCommand = git.push();
pushCommand.setProgressMonitor(gitMonitor);
pushCommand.setTransportConfigCallback(new TransportConfigCallback() {
@Override
public void configure(Transport t) {
credentials.setUri(t.getURI());
if (t instanceof TransportHttp && cookie != null) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(GitConstants.KEY_COOKIE, cookie.getName() + "=" + cookie.getValue());
((TransportHttp) t).setAdditionalHeaders(map);
}
}
});
RemoteConfig remoteConfig = new RemoteConfig(git.getRepository().getConfig(), remote);
credentials.setUri(remoteConfig.getURIs().get(0));
pushCommand.setCredentialsProvider(credentials);
boolean pushToGerrit = branch.startsWith("for/");
RefSpec spec = new RefSpec(srcRef + ':' + (pushToGerrit ? "refs/" : Constants.R_HEADS) + branch);
pushCommand.setRemote(remote).setRefSpecs(spec);
if (tags)
pushCommand.setPushTags();
pushCommand.setForce(force);
Iterable<PushResult> resultIterable = pushCommand.call();
if (monitor.isCanceled()) {
return new Status(IStatus.CANCEL, GitActivator.PI_GIT, "Cancelled");
}
PushResult pushResult = resultIterable.iterator().next();
boolean error = false;
JSONArray updates = new JSONArray();
result.put(GitConstants.KEY_COMMIT_MESSAGE, pushResult.getMessages());
result.put(GitConstants.KEY_UPDATES, updates);
for (final RemoteRefUpdate rru : pushResult.getRemoteUpdates()) {
if (monitor.isCanceled()) {
return new Status(IStatus.CANCEL, GitActivator.PI_GIT, "Cancelled");
}
final String rm = rru.getRemoteName();
// check status only for branch given in the URL or tags
if (branch.equals(Repository.shortenRefName(rm)) || rm.startsWith(Constants.R_TAGS) || rm.startsWith(Constants.R_REFS + "for/")) {
JSONObject object = new JSONObject();
RemoteRefUpdate.Status status = rru.getStatus();
if (status != RemoteRefUpdate.Status.UP_TO_DATE || !rm.startsWith(Constants.R_TAGS)) {
object.put(GitConstants.KEY_COMMIT_MESSAGE, rru.getMessage());
object.put(GitConstants.KEY_RESULT, status.name());
TrackingRefUpdate refUpdate = rru.getTrackingRefUpdate();
if (refUpdate != null) {
object.put(GitConstants.KEY_REMOTENAME, Repository.shortenRefName(refUpdate.getLocalName()));
object.put(GitConstants.KEY_LOCALNAME, Repository.shortenRefName(refUpdate.getRemoteName()));
} else {
object.put(GitConstants.KEY_REMOTENAME, Repository.shortenRefName(rru.getSrcRef()));
object.put(GitConstants.KEY_LOCALNAME, Repository.shortenRefName(rru.getRemoteName()));
}
updates.put(object);
}
if (status != RemoteRefUpdate.Status.OK && status != RemoteRefUpdate.Status.UP_TO_DATE)
error = true;
}
// TODO: return results for all updated branches once push is available for remote, see bug 352202
}
// needs to handle multiple
result.put("Severity", error ? "Error" : "Ok");
} catch (JSONException e) {
} finally {
if (db != null) {
db.close();
}
}
return new ServerStatus(Status.OK_STATUS, HttpServletResponse.SC_OK, result);
}
public abstract GitTransportUpdate createTransportUpdate (URIish urI, TrackingRefUpdate update);