Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 353405

Summary: PushCommand should push all branches existing on the remote if no push RefSpec is given
Product: [Technology] JGit Reporter: Piotr Janik <janikpiotrek>
Component: JGitAssignee: Project Inbox <jgit.core-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: caniszczyk, christian.halstrick, christian.halstrick, matthias.sohn, pwebster, robin, stefan.lay, Szymon.Brandys, tomasz.zarna, twolf
Version: 1.1   
Target Milestone: 6.1   
Hardware: All   
OS: All   
URL: https://git.eclipse.org/r/#/c/4022/
See Also: https://git.eclipse.org/r/c/jgit/jgit/+/190980
https://git.eclipse.org/c/jgit/jgit.git/commit/?id=8a2c76941729629dce06e2238464e114f2ccc79a
Whiteboard:
Bug Depends on:    
Bug Blocks: 352202    

Description Piotr Janik CLA 2011-07-29 08:37:36 EDT
1. Create two clones of the same repo
2. Make sure they have at least two remote branches and that they're in sync
3. In the first clone, make changes on both branches and commit them, do not
push yet
4. do "git push remote_name" 
Git git = new Git(db);
git.push().setRemote(remote).call();
=> SHOULD BE: changes from both branches should be pushed (like in Git Bash).
=> IS: only HEAD branch is pushed.

probably caused by that lines:
PushCommand.call() {
[ ... ]
if (refSpecs.isEmpty()) {
  RemoteConfig config = new RemoteConfig(repo.getConfig(),
  getRemote());
  refSpecs.addAll(config.getPushRefSpecs());
}
if (refSpecs.isEmpty()) {
 Ref head = repo.getRef(Constants.HEAD);
 if (head != null && head.isSymbolic())
  refSpecs.add(new RefSpec(head.getLeaf().getName()));
}
[...]
Comment 1 Tomasz Zarna CLA 2011-08-17 10:41:48 EDT
In other words, if a branch exists remotely there is no need to specify a refspec or use --all flag to push its changes. In cgit, doing "git push <remote>" is enough to push commits from all branches.

Workaround: if you're not setting a refspec to push, don't forget to call PushCommand.setPushAll().
Comment 2 Tomasz Zarna CLA 2011-08-17 10:46:05 EDT
A failing test case: http://egit.eclipse.org/r/4022
Comment 3 Tomasz Zarna CLA 2011-10-03 04:42:04 EDT
A fix has been proposed on http://egit.eclipse.org/r/#change,4022.
Comment 4 Szymon Brandys CLA 2011-11-07 05:31:46 EST
Ping. Could someone from the JGit team review the suggested fix, please.
Comment 5 Tomasz Zarna CLA 2012-03-15 08:42:47 EDT
https://git.eclipse.org/r/#/c/4022/ has been rebased, still waiting for a comment.
Comment 6 Robin Stocker CLA 2012-04-28 08:03:14 EDT
By the way, C Git is discussing a change of what "git push" without arguments should actually do (matching, upstream, current):

https://lwn.net/Articles/487131/

I don't know what the current state of the discussion is, but we should probably follow the decision in JGit.
Comment 7 Eclipse Genie CLA 2022-02-19 11:51:45 EST
New Gerrit change created: https://git.eclipse.org/r/c/jgit/jgit/+/190980
Comment 8 Thomas Wolf CLA 2022-02-19 12:13:58 EST
(In reply to Eclipse Genie from comment #7)
> New Gerrit change created: https://git.eclipse.org/r/c/jgit/jgit/+/190980

The default value for push.default is nowadays "simple".

JGit has traditionally implemented "current", and that is still the default for PushCommand. PushCommand has gotten a setPushDefault() operation to set an explicit mode, though, that would be used if no RefSpecs are given. setPushDefault(null) would make it use the git config.

setPushAll() as mentioned in comment 1 is not a valid work-around, it would also push local branches for which the remote has no corresponding branch yet.

The above change implements the ":" and "+:" RefSpecs, and uses ":" if a push.default of "matching" is active and no RefSpec was given. (It'll also use it if given explicitly.)