2 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org
.spearce
.jgit
.pgm
;
40 import java
.util
.ArrayList
;
41 import java
.util
.Collection
;
42 import java
.util
.List
;
44 import org
.kohsuke
.args4j
.Argument
;
45 import org
.kohsuke
.args4j
.Option
;
46 import org
.spearce
.jgit
.lib
.Ref
;
47 import org
.spearce
.jgit
.lib
.TextProgressMonitor
;
48 import org
.spearce
.jgit
.transport
.PushResult
;
49 import org
.spearce
.jgit
.transport
.RefSpec
;
50 import org
.spearce
.jgit
.transport
.RemoteRefUpdate
;
51 import org
.spearce
.jgit
.transport
.Transport
;
52 import org
.spearce
.jgit
.transport
.RemoteRefUpdate
.Status
;
54 class Push
extends TextBuiltin
{
55 @Argument(index
= 0, metaVar
= "uri-ish")
56 private String remote
= "origin";
58 @Argument(index
= 1, metaVar
= "refspec")
59 private final List
<RefSpec
> refSpecs
= new ArrayList
<RefSpec
>();
61 @Option(name
= "--all")
62 void addAll(final boolean ignored
) {
63 refSpecs
.add(Transport
.REFSPEC_PUSH_ALL
);
66 @Option(name
= "--tags")
67 void addTags(final boolean ignored
) {
68 refSpecs
.add(Transport
.REFSPEC_TAGS
);
71 @Option(name
= "--verbose", aliases
= { "-v" })
72 private boolean verbose
= false;
74 @Option(name
= "--thin")
75 private boolean thin
= Transport
.DEFAULT_PUSH_THIN
;
77 @Option(name
= "--no-thin")
78 void nothin(final boolean ignored
) {
82 @Option(name
= "--force", aliases
= { "-f" })
83 private boolean force
;
85 @Option(name
= "--receive-pack", metaVar
= "path")
86 private String receivePack
;
88 private boolean first
= true;
91 protected void run() throws Exception
{
93 final List
<RefSpec
> orig
= new ArrayList
<RefSpec
>(refSpecs
);
95 for (final RefSpec spec
: orig
)
96 refSpecs
.add(spec
.setForceUpdate(true));
99 final Transport transport
= Transport
.open(db
, remote
);
100 transport
.setPushThin(thin
);
101 if (receivePack
!= null)
102 transport
.setOptionReceivePack(receivePack
);
103 final Collection
<RemoteRefUpdate
> toPush
= transport
104 .findRemoteRefUpdatesFor(refSpecs
);
106 final PushResult result
= transport
.push(new TextProgressMonitor(),
110 printPushResult(result
);
113 private void printPushResult(final PushResult result
) {
114 boolean everythingUpToDate
= true;
115 // at first, print up-to-date ones...
116 for (final RemoteRefUpdate rru
: result
.getRemoteUpdates()) {
117 if (rru
.getStatus() == Status
.UP_TO_DATE
) {
119 printRefUpdateResult(result
, rru
);
121 everythingUpToDate
= false;
124 for (final RemoteRefUpdate rru
: result
.getRemoteUpdates()) {
125 // ...then successful updates...
126 if (rru
.getStatus() == Status
.OK
)
127 printRefUpdateResult(result
, rru
);
130 for (final RemoteRefUpdate rru
: result
.getRemoteUpdates()) {
131 // ...finally, others (problematic)
132 if (rru
.getStatus() != Status
.OK
133 && rru
.getStatus() != Status
.UP_TO_DATE
)
134 printRefUpdateResult(result
, rru
);
137 if (everythingUpToDate
)
138 out
.println("Everything up-to-date");
141 private void printRefUpdateResult(final PushResult result
,
142 final RemoteRefUpdate rru
) {
145 out
.format("To %s\n", result
.getURI());
148 final String remoteName
= rru
.getRemoteName();
149 final String srcRef
= rru
.isDelete() ?
null : rru
.getSrcRef();
151 switch (rru
.getStatus()) {
154 printUpdateLine('-', "[deleted]", null, remoteName
, null);
156 final Ref oldRef
= result
.getAdvertisedRef(remoteName
);
157 if (oldRef
== null) {
158 final String summary
;
159 if (remoteName
.startsWith(REFS_TAGS
))
160 summary
= "[new tag]";
162 summary
= "[new branch]";
163 printUpdateLine('*', summary
, srcRef
, remoteName
, null);
165 boolean fastForward
= rru
.isFastForward();
166 final char flag
= fastForward ?
' ' : '+';
167 final String summary
= abbreviateObject(oldRef
169 + (fastForward ?
".." : "...")
170 + abbreviateObject(rru
.getNewObjectId());
171 final String message
= fastForward ?
null : "forced update";
172 printUpdateLine(flag
, summary
, srcRef
, remoteName
, message
);
178 printUpdateLine('X', "[no match]", null, remoteName
, null);
181 case REJECTED_NODELETE
:
182 printUpdateLine('!', "[rejected]", null, remoteName
,
183 "remote side does not support deleting refs");
186 case REJECTED_NONFASTFORWARD
:
187 printUpdateLine('!', "[rejected]", srcRef
, remoteName
,
191 case REJECTED_REMOTE_CHANGED
:
192 final String message
= "remote ref object changed - is not expected one "
193 + abbreviateObject(rru
.getExpectedOldObjectId());
194 printUpdateLine('!', "[rejected]", srcRef
, remoteName
, message
);
197 case REJECTED_OTHER_REASON
:
198 printUpdateLine('!', "[remote rejected]", srcRef
, remoteName
, rru
204 printUpdateLine('=', "[up to date]", srcRef
, remoteName
, null);
208 case AWAITING_REPORT
:
209 printUpdateLine('?', "[unexpected push-process behavior]", srcRef
,
210 remoteName
, rru
.getMessage());
215 private void printUpdateLine(final char flag
, final String summary
,
216 final String srcRef
, final String destRef
, final String message
) {
217 out
.format(" %c %-17s", flag
, summary
);
220 out
.format(" %s ->", abbreviateRef(srcRef
, true));
221 out
.format(" %s", abbreviateRef(destRef
, true));
224 out
.format(" (%s)", message
);