Skip to content

Commit 954d4b9

Browse files
committed
cli git push: always allow pushing explicitly named bookmarks
By explicitly naming the bookmark to push, users already express their intent to push that particular bookmark. Requiring them to express that intent a second time by manually marking the bookmark as tracked is therefore unnecessary.
1 parent 8c84656 commit 954d4b9

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
2424
filesystem's behavior, but this can be overridden manually by setting
2525
`working-copy.exec-bit-change = "respect" | "ignore"`.
2626

27+
* `jj git push --bookmark <name>` will now automatically track the bookmark in
28+
cases where the user intent is unambiguous.
29+
2730
### Fixed bugs
2831

2932
* Broken symlink on Windows. [#6934](https://github.com/jj-vcs/jj/issues/6934).

cli/src/commands/git/push.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use jj_lib::revset::RevsetExpression;
4949
use jj_lib::settings::UserSettings;
5050
use jj_lib::signing::SignBehavior;
5151
use jj_lib::str_util::StringExpression;
52+
use jj_lib::str_util::StringMatcher;
5253
use jj_lib::view::View;
5354

5455
use crate::cli_util::CommandHelper;
@@ -349,6 +350,36 @@ pub fn cmd_git_push(
349350
continue;
350351
}
351352
let remote_symbol = name.to_remote_symbol(remote);
353+
// Check for some targeted allow_new overrides. These are
354+
// conservative heuristics, rather than principled rules. They
355+
// should cover most practical situations without causing harm.
356+
let allow_new = if args.bookmark.iter().any(|b| b.contains(':')) {
357+
// The user specified bookmarks with something more complicated
358+
// than exact matching. It's possible that some bookmarks which
359+
// shouldn't be pushed are matched by mistake. Therefore, do not
360+
// override allow_new.
361+
allow_new
362+
} else if args.remote.is_some() {
363+
// The user specified all bookmarks exactly and provided an
364+
// explicit remote to push to. Since the user's intent is
365+
// unambiguous, allow the bookmark to be pushed.
366+
true
367+
} else if view
368+
.remote_bookmarks_matching(&StringMatcher::Exact(name.into()), &StringMatcher::All)
369+
.any(|(_, target)| target.is_tracked())
370+
{
371+
// The bookmark is already tracked with some remote. If it
372+
// is not tracked with the default remote being pushed to,
373+
// there is a good chance the user meant to push the bookmark
374+
// to the remote it's already tracking, but forgot to supply
375+
// `--remote`. Therefore, do not override allow_new.
376+
allow_new
377+
} else {
378+
// The user specified this bookmark exactly and it is not
379+
// tracked with any other remote. The user unambiguously intends
380+
// to push this new bookmark to the default remote.
381+
true
382+
};
352383
let allow_delete = true; // named explicitly, allow delete without --delete
353384
match classify_bookmark_update(remote_symbol, targets, allow_new, allow_delete) {
354385
Ok(Some(update)) => bookmark_updates.push((name.to_owned(), update)),

cli/tests/test_git_push.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,7 @@ fn test_git_push_mixed() {
13691369
.success();
13701370
work_dir.write_file("file", "modified again");
13711371

1372-
// --allow-new is not implied for --bookmark=.. and -r=..
1372+
// --allow-new is not implied for -r=..
13731373
let output = work_dir.run_jj([
13741374
"git",
13751375
"push",
@@ -1380,10 +1380,14 @@ fn test_git_push_mixed() {
13801380
insta::assert_snapshot!(output, @r"
13811381
------- stderr -------
13821382
Creating bookmark push-yqosqzytrlsw for revision yqosqzytrlsw
1383-
Error: Refusing to create new remote bookmark bookmark-1@origin
1384-
Hint: Run `jj bookmark track bookmark-1@origin` and try again.
1383+
Warning: Refusing to create new remote bookmark bookmark-2a@origin
1384+
Hint: Run `jj bookmark track bookmark-2a@origin` and try again.
1385+
Warning: Refusing to create new remote bookmark bookmark-2b@origin
1386+
Hint: Run `jj bookmark track bookmark-2b@origin` and try again.
1387+
Changes to push to origin:
1388+
Add bookmark push-yqosqzytrlsw to 0f8164cd580b
1389+
Add bookmark bookmark-1 to e76139e55e1e
13851390
[EOF]
1386-
[exit status: 1]
13871391
");
13881392

13891393
let output = work_dir.run_jj([
@@ -1397,10 +1401,9 @@ fn test_git_push_mixed() {
13971401
insta::assert_snapshot!(output, @r"
13981402
------- stderr -------
13991403
Warning: --allow-new is deprecated, track bookmarks manually or configure remotes.<name>.auto-track-bookmarks instead.
1400-
Creating bookmark push-yqosqzytrlsw for revision yqosqzytrlsw
1404+
Bookmark push-yqosqzytrlsw@origin already matches push-yqosqzytrlsw
1405+
Bookmark bookmark-1@origin already matches bookmark-1
14011406
Changes to push to origin:
1402-
Add bookmark push-yqosqzytrlsw to 0f8164cd580b
1403-
Add bookmark bookmark-1 to e76139e55e1e
14041407
Add bookmark bookmark-2a to 57d822f901bb
14051408
Add bookmark bookmark-2b to 57d822f901bb
14061409
[EOF]

0 commit comments

Comments
 (0)