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
.Collection
;
41 import java
.util
.LinkedList
;
43 import org
.spearce
.jgit
.lib
.Ref
;
44 import org
.spearce
.jgit
.lib
.TextProgressMonitor
;
45 import org
.spearce
.jgit
.transport
.PushResult
;
46 import org
.spearce
.jgit
.transport
.RefSpec
;
47 import org
.spearce
.jgit
.transport
.RemoteRefUpdate
;
48 import org
.spearce
.jgit
.transport
.Transport
;
49 import org
.spearce
.jgit
.transport
.RemoteRefUpdate
.Status
;
51 class Push
extends TextBuiltin
{
53 private boolean verbose
= false;
55 private Transport transport
;
57 private boolean first
= true;
60 void execute(String
[] args
) throws Exception
{
61 final LinkedList
<RefSpec
> refSpecs
= new LinkedList
<RefSpec
>();
64 boolean forceAll
= false;
67 for (; argi
< args
.length
; argi
++) {
68 final String a
= args
[argi
];
69 if ("--thin".equals(a
))
71 else if ("--no-thin".equals(a
))
73 else if ("-f".equals(a
) || "--force".equals(a
))
75 else if (a
.startsWith("--exec="))
76 exec
= a
.substring("--exec=".length());
77 else if (a
.startsWith("--receive-pack="))
78 exec
= a
.substring("--receive-pack=".length());
79 else if ("--tags".equals(a
))
80 refSpecs
.add(Transport
.REFSPEC_TAGS
);
81 else if ("--all".equals(a
))
82 refSpecs
.add(Transport
.REFSPEC_PUSH_ALL
);
83 else if ("-v".equals(a
))
85 else if ("--".equals(a
)) {
88 } else if (a
.startsWith("-"))
89 die("usage: push [--all] [--tags] [--force] [--thin]\n"
90 + "[--receive-pack=<git-receive-pack>] [<repository> [<refspec>]...]");
95 final String repository
;
96 if (argi
== args
.length
)
97 repository
= "origin";
99 repository
= args
[argi
++];
100 transport
= Transport
.open(db
, repository
);
102 transport
.setPushThin(thin
);
104 transport
.setOptionReceivePack(exec
);
106 for (; argi
< args
.length
; argi
++) {
107 RefSpec spec
= new RefSpec(args
[argi
]);
109 spec
= spec
.setForceUpdate(true);
112 final Collection
<RemoteRefUpdate
> toPush
= transport
113 .findRemoteRefUpdatesFor(refSpecs
);
115 final PushResult result
= transport
.push(new TextProgressMonitor(),
117 printPushResult(result
);
120 private void printPushResult(final PushResult result
) {
121 boolean everythingUpToDate
= true;
122 // at first, print up-to-date ones...
123 for (final RemoteRefUpdate rru
: result
.getRemoteUpdates()) {
124 if (rru
.getStatus() == Status
.UP_TO_DATE
) {
126 printRefUpdateResult(result
, rru
);
128 everythingUpToDate
= false;
131 for (final RemoteRefUpdate rru
: result
.getRemoteUpdates()) {
132 // ...then successful updates...
133 if (rru
.getStatus() == Status
.OK
)
134 printRefUpdateResult(result
, rru
);
137 for (final RemoteRefUpdate rru
: result
.getRemoteUpdates()) {
138 // ...finally, others (problematic)
139 if (rru
.getStatus() != Status
.OK
140 && rru
.getStatus() != Status
.UP_TO_DATE
)
141 printRefUpdateResult(result
, rru
);
144 if (everythingUpToDate
)
145 out
.println("Everything up-to-date");
148 private void printRefUpdateResult(final PushResult result
,
149 final RemoteRefUpdate rru
) {
152 out
.format("To %s\n", transport
.getURI());
155 final String remoteName
= rru
.getRemoteName();
156 final String srcRef
= rru
.isDelete() ?
null : rru
.getSrcRef();
158 switch (rru
.getStatus()) {
161 printUpdateLine('-', "[deleted]", null, remoteName
, null);
163 final Ref oldRef
= result
.getAdvertisedRef(remoteName
);
164 if (oldRef
== null) {
165 final String summary
;
166 if (remoteName
.startsWith(REFS_TAGS
))
167 summary
= "[new tag]";
169 summary
= "[new branch]";
170 printUpdateLine('*', summary
, srcRef
, remoteName
, null);
172 boolean fastForward
= rru
.isFastForward();
173 final char flag
= fastForward ?
' ' : '+';
174 final String summary
= abbreviateObject(oldRef
176 + (fastForward ?
".." : "...")
177 + abbreviateObject(rru
.getNewObjectId());
178 final String message
= fastForward ?
null : "forced update";
179 printUpdateLine(flag
, summary
, srcRef
, remoteName
, message
);
185 printUpdateLine('X', "[no match]", null, remoteName
, null);
188 case REJECTED_NODELETE
:
189 printUpdateLine('!', "[rejected]", null, remoteName
,
190 "remote side does not support deleting refs");
193 case REJECTED_NONFASTFORWARD
:
194 printUpdateLine('!', "[rejected]", srcRef
, remoteName
,
198 case REJECTED_REMOTE_CHANGED
:
199 final String message
= "remote ref object changed - is not expected one "
200 + abbreviateObject(rru
.getExpectedOldObjectId());
201 printUpdateLine('!', "[rejected]", srcRef
, remoteName
, message
);
204 case REJECTED_OTHER_REASON
:
205 printUpdateLine('!', "[remote rejected]", srcRef
, remoteName
, rru
211 printUpdateLine('=', "[up to date]", srcRef
, remoteName
, null);
215 case AWAITING_REPORT
:
216 printUpdateLine('?', "[unexpected push-process behavior]", srcRef
,
217 remoteName
, rru
.getMessage());
222 private void printUpdateLine(final char flag
, final String summary
,
223 final String srcRef
, final String destRef
, final String message
) {
224 out
.format(" %c %-17s", flag
, summary
);
227 out
.format(" %s ->", abbreviateRef(srcRef
, true));
228 out
.format(" %s", abbreviateRef(destRef
, true));
231 out
.format(" (%s)", message
);