@codebend3r/che 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,42 +1,35 @@
1
1
  #!/usr/bin/env python3
2
- """🔄 Sync every branch: delete merged ones, rebase the rest, check out new ones.
2
+ """🔄 Update every branch and worktree, keeping checkouts, locks and local work.
3
3
 
4
- Steps, in order:
5
- 1. Switch the main clone to the main branch
6
- 2. Fetch + prune every remote, once for the whole run
7
- 3. clean-stale-branches (delete branches whose upstream is gone)
8
- 4. update-local-branches (rebase every branch onto its upstream)
9
- 5. checkout-my-branches (track your remote branches that aren't local)
10
-
11
- Only branches change. It never pushes, never adds, removes or prunes a
12
- worktree, and never runs a repo's git hooks: pushing and worktrees are the
13
- user's call, and a lefthook or husky pre-commit or pre-push gates the user's
14
- own work, not this bookkeeping. A branch checked out in a linked worktree is
15
- rebased in place there; a stale one is reported, not deleted. The main clone
16
- ends on main: new branches are created without being checked out.
4
+ Fetch once, rebase branches onto their upstream (or origin/<branch>), and track
5
+ new origin branches authored by you. Dirty tracked/untracked work is saved in
6
+ an exact recovery stash and restored with its index. Conflicts are reported;
7
+ independent branches continue. Nothing is pushed, hard reset or deleted.
17
8
 
18
9
  Usage:
19
10
  sync-all-branches.py [--dry-run] [--author=EMAIL] [--limit=N]
20
11
 
21
12
  Options:
22
- --dry-run Report what would be deleted / synced, change nothing
23
- --author=EMAIL Passed through to checkout-my-branches
24
- --limit=N Passed through to checkout-my-branches
13
+ --dry-run Preview cached refs only; no fetch or changes
14
+ --author=EMAIL Author of new origin branches (default: git config user.email)
15
+ --limit=N Recent origin refs to scan for new branches (default: 100)
25
16
  --help Show help
26
17
 
27
18
  Env:
28
- DRY_RUN=true Same as --dry-run (used by the .zshrc -dr wrapper)
19
+ DRY_RUN=true Same as --dry-run (used by the shell -dr wrapper)
29
20
  """
30
21
 
31
22
  from __future__ import annotations
32
23
 
33
24
  import argparse
25
+ import subprocess
34
26
  import sys
35
27
  from pathlib import Path
36
28
 
37
29
  sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
38
30
 
39
- from gitutils import fetch_remotes, park_main_worktree, skip_git_hooks
31
+ from branchsync import BranchSync
32
+ from gitutils import current_branch, fetch_remotes, for_each_ref, local_branches, skip_git_hooks
40
33
  from utils import (
41
34
  add_bool_flag,
42
35
  build_parser,
@@ -44,94 +37,108 @@ from utils import (
44
37
  heading,
45
38
  info,
46
39
  log,
40
+ parse_count,
47
41
  require_binary,
48
42
  run,
49
43
  run_cli,
44
+ run_output,
45
+ warning,
50
46
  )
51
47
 
52
- __version__ = "2.1.0"
53
-
54
- SCRIPT_DIR = Path(__file__).resolve().parent
55
-
56
-
57
- def delegate(script: str, args: list[str], *, cwd: Path) -> None:
58
- """Run a sibling script in the main worktree, aborting the sync if it fails.
48
+ __version__ = "3.0.0"
59
49
 
60
- The shell version invoked these under ``set -e``, so a non-zero exit from
61
- any of them ended the run. ``check=True`` reproduces that: a branch that
62
- could not be rebased is a reason to stop and look, not to sail on.
63
50
 
64
- The blank line before each one is flushed: a child writes straight to the
65
- shared stdout, so an unflushed separator would surface after its output
66
- whenever the sync is piped.
67
- """
68
- print(flush=True)
69
- run([sys.executable, str(SCRIPT_DIR / script), *args], cwd=cwd)
51
+ def track_new(sync: BranchSync, author: str, limit: int) -> list[str]:
52
+ tracked: list[str] = []
53
+ local = {branch for (branch,) in local_branches(cwd=sync.root)}
54
+ refs = for_each_ref(
55
+ "refs/remotes/origin/",
56
+ "authoremail:trim",
57
+ "refname:lstrip=3",
58
+ "symref",
59
+ sort="-committerdate",
60
+ cwd=sync.root,
61
+ )
62
+ for email, branch, symref in refs[:limit]:
63
+ if symref or email != author or branch in local:
64
+ continue
65
+ if sync.dry_run:
66
+ info(f"🌵 Would track: {branch}")
67
+ continue
68
+ if run(
69
+ ["git", "branch", "--track", branch, f"refs/remotes/origin/{branch}"],
70
+ cwd=sync.root,
71
+ check=False,
72
+ ).returncode:
73
+ sync.block(branch, "could not create tracking branch")
74
+ else:
75
+ tracked.append(branch)
76
+ return tracked
70
77
 
71
78
 
72
79
  def main(argv: list[str] | None = None) -> int:
73
80
  parser = build_parser(
74
81
  prog="sync-all-branches",
75
- description="🔄 Delete merged branches, rebase the rest, check out new ones.",
82
+ description="🔄 Update every branch and worktree, preserving locks and local work.",
76
83
  )
77
84
  add_bool_flag(
78
85
  parser,
79
86
  "--dry-run",
80
87
  default=env_bool("DRY_RUN", False),
81
- help="Report what would be deleted / synced, change nothing",
88
+ help="Preview cached refs only; no fetch or changes",
82
89
  )
83
- # Accepted and ignored, from when the sync pushed and collapsed worktrees:
84
- # chip's "Update from Origin" still passes --no-push and must keep running.
90
+ # Compatibility with chip and older wrappers. Neither pushing nor lock
91
+ # removal is ever part of syncing, regardless of these legacy flags.
85
92
  add_bool_flag(parser, "--no-push", allow_value=False, help=argparse.SUPPRESS)
86
93
  add_bool_flag(parser, "--keep-locked", help=argparse.SUPPRESS)
87
94
  parser.add_argument(
88
95
  "--author",
89
96
  default="",
90
97
  metavar="EMAIL",
91
- help="Passed through to checkout-my-branches",
98
+ help="Author of new origin branches (default: git config user.email)",
92
99
  )
93
100
  parser.add_argument(
94
101
  "--limit",
95
- default="",
102
+ default="100",
96
103
  metavar="N",
97
- help="Passed through to checkout-my-branches",
104
+ help="Recent origin refs to scan for new branches (default: 100)",
98
105
  )
99
106
  args = parser.parse_args(argv)
100
-
107
+ limit = parse_count(args.limit, "--limit", minimum=1)
101
108
  require_binary("git")
102
109
  skip_git_hooks()
103
-
104
110
  heading("🔄 sync-all-branches", dry_run=args.dry_run)
105
-
106
- # Every later step runs from the main worktree, because the delegated
107
- # scripts expect the main clone. Passing cwd= to each call rather than
108
- # `cd`-ing keeps the process's own directory untouched.
109
- main_wt = park_main_worktree("sync", dry_run=args.dry_run)
110
-
111
- # The one fetch of the run. Each delegated script fetches when run on its
112
- # own; here they inherit the marker fetch_remotes leaves and skip theirs.
113
- fetch_remotes()
114
-
115
- # Dry-run travels as an explicit --dry-run=true|false, never as DRY_RUN in
116
- # the environment, so a child can never disagree with the parent about
117
- # which mode this is - whatever DRY_RUN it inherited.
118
- mode = [f"--dry-run={'true' if args.dry_run else 'false'}"]
119
- delegate("clean-stale-branches.py", mode, cwd=main_wt)
120
- delegate("update-local-branches.py", mode, cwd=main_wt)
121
-
122
- checkout_args = []
123
- if args.author:
124
- checkout_args.append(f"--author={args.author}")
125
- if args.limit:
126
- checkout_args.append(f"--limit={args.limit}")
127
-
111
+ if run_output(["git", "rev-parse", "--is-inside-work-tree"], check=False) != "true":
112
+ warning("❌ Not inside a git working tree.")
113
+ return 1
114
+ root = Path(run_output(["git", "rev-parse", "--show-toplevel"]))
115
+ author = args.author or run_output(["git", "config", "user.email"], cwd=root, check=False)
116
+ if not author:
117
+ warning("❌ No author email; pass --author=EMAIL or set git config user.email.")
118
+ return 1
119
+ original = current_branch(root) or run_output(["git", "rev-parse", "--short", "HEAD"], cwd=root)
120
+ info(f"📍 Keeping caller checkout: {original}")
121
+ # DELIBERATE DIVERGENCE: the old sync parked on main and delegated cleanup.
122
+ # Preserve active workspaces instead, and never discard a gone-upstream
123
+ # branch merely because its remote was deleted. Dry-run must not fetch.
128
124
  if args.dry_run:
129
- print(flush=True)
130
- info(f"🌵 Would run: checkout-my-branches {' '.join(checkout_args)}".rstrip())
125
+ info("🌵 Cached remote refs only; no fetch. Results reflect the last fetch.")
131
126
  else:
132
- delegate("checkout-my-branches.py", checkout_args, cwd=main_wt)
133
-
134
- log("🎉 Sync complete.")
127
+ fetch_remotes()
128
+ sync = BranchSync(root, args.dry_run)
129
+ sync.update()
130
+ try:
131
+ tracked = track_new(sync, author, limit)
132
+ except (subprocess.CalledProcessError, OSError) as exc:
133
+ sync.block("new origin branches", str(exc))
134
+ tracked = []
135
+ sync.summary(tracked)
136
+ if sync.blocked:
137
+ warning(
138
+ "Sync partially completed; blocked branches need attention. Remaining independent branches were attempted."
139
+ )
140
+ return 1
141
+ log("🎉 Preview complete." if args.dry_run else "🎉 Sync complete.")
135
142
  return 0
136
143
 
137
144
 
package/bin/gitutils.py CHANGED
@@ -150,12 +150,12 @@ def worktrees(cwd: str | Path | None = None) -> list[Worktree]:
150
150
  The first entry is always the main worktree; callers drop it themselves so
151
151
  the distinction stays explicit at the call site.
152
152
 
153
- The shell version parsed this with ``awk '{print $2}'``, which splits on
154
- whitespace and so truncated any worktree path containing a space. Taking
155
- the whole remainder of the line keeps such paths intact.
153
+ DELIBERATE DIVERGENCE: the shell version split on whitespace. NUL-delimited
154
+ porcelain preserves spaces, tabs, backslashes and newlines in paths without
155
+ Git's quoted-path escaping, so commands can route to the exact checkout.
156
156
  """
157
157
  found: list[Worktree] = []
158
- for line in run_output(["git", "worktree", "list", "--porcelain"], cwd=cwd).splitlines():
158
+ for line in run_output(["git", "worktree", "list", "--porcelain", "-z"], cwd=cwd).split("\0"):
159
159
  if line.startswith("worktree "):
160
160
  found.append(Worktree(line.removeprefix("worktree "), ""))
161
161
  elif line.startswith("branch refs/heads/"):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebend3r/che",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Helper scripts shared across machines, called by name from your shell and browsable through one menu",
5
5
  "keywords": [
6
6
  "cli",
package/shell/che.bash CHANGED
@@ -1,4 +1,4 @@
1
- # che 1.2.0 - generated file, do not edit.
1
+ # che 1.2.2 - generated file, do not edit.
2
2
  #
3
3
  # Generated from bin/commands.py by `che install`.
4
4
  # To change a wrapper, edit that manifest and run `che install` again.
@@ -59,7 +59,8 @@ _che_restore_aliases() {
59
59
 
60
60
  _che_stash_aliases che_notify che all-actions all-actions-watch \
61
61
  checkout-my-branches clean-stale-branches clean-stale-branches-dr \
62
- prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr \
62
+ hard-reset-all-branches hard-reset-all-branches-dr prune-worktrees \
63
+ prune-worktrees-dr sync-all-branches sync-all-branches-dr \
63
64
  update-from-origin update-local-branches show-codecs fix-codecs \
64
65
  fix-codecs-dr find-video-mkv-issues validate-video-files \
65
66
  scan-videos-audio-language remove-metadata rename-video-file \
@@ -126,6 +127,18 @@ clean-stale-branches-dr() {
126
127
  che_notify 7 $?
127
128
  }
128
129
 
130
+ # Check out every local branch and hard reset it to origin/<branch>
131
+ hard-reset-all-branches() {
132
+ DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/hard-reset-all-branches.py" "$@"
133
+ che_notify 4 $?
134
+ }
135
+
136
+ # Check out every local branch and hard reset it to origin/<branch> (preview only)
137
+ hard-reset-all-branches-dr() {
138
+ DRY_RUN=true "$CHE_PYTHON" "$CHE_BIN/git/hard-reset-all-branches.py" "$@"
139
+ che_notify 7 $?
140
+ }
141
+
129
142
  # Remove every linked worktree, then prune stale admin records
130
143
  prune-worktrees() {
131
144
  DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/prune-worktrees.py" "$@"
@@ -138,13 +151,13 @@ prune-worktrees-dr() {
138
151
  che_notify 7 $?
139
152
  }
140
153
 
141
- # Delete merged branches, rebase the rest, check out new ones; branches only
154
+ # Update every branch and worktree, preserving locks and local work
142
155
  sync-all-branches() {
143
156
  DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/sync-all-branches.py" "$@"
144
157
  che_notify 7 $?
145
158
  }
146
159
 
147
- # Delete merged branches, rebase the rest, check out new ones; branches only (preview only)
160
+ # Update every branch and worktree, preserving locks and local work (preview only)
148
161
  sync-all-branches-dr() {
149
162
  DRY_RUN=true "$CHE_PYTHON" "$CHE_BIN/git/sync-all-branches.py" "$@"
150
163
  che_notify 7 $?
package/shell/che.fish CHANGED
@@ -1,4 +1,4 @@
1
- # che 1.2.0 - generated file, do not edit.
1
+ # che 1.2.2 - generated file, do not edit.
2
2
  #
3
3
  # Generated from bin/commands.py by `che install`.
4
4
  # To change a wrapper, edit that manifest and run `che install` again.
@@ -68,6 +68,16 @@ function clean-stale-branches-dr --description 'Delete local branches whose upst
68
68
  che_notify 7 $status
69
69
  end
70
70
 
71
+ function hard-reset-all-branches --description 'Check out every local branch and hard reset it to origin/<branch>'
72
+ env DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/hard-reset-all-branches.py" $argv
73
+ che_notify 4 $status
74
+ end
75
+
76
+ function hard-reset-all-branches-dr --description 'Check out every local branch and hard reset it to origin/<branch> (preview only)'
77
+ env DRY_RUN=true "$CHE_PYTHON" "$CHE_BIN/git/hard-reset-all-branches.py" $argv
78
+ che_notify 7 $status
79
+ end
80
+
71
81
  function prune-worktrees --description 'Remove every linked worktree, then prune stale admin records'
72
82
  env DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/prune-worktrees.py" $argv
73
83
  che_notify 4 $status
@@ -78,12 +88,12 @@ function prune-worktrees-dr --description 'Remove every linked worktree, then pr
78
88
  che_notify 7 $status
79
89
  end
80
90
 
81
- function sync-all-branches --description 'Delete merged branches, rebase the rest, check out new ones; branches only'
91
+ function sync-all-branches --description 'Update every branch and worktree, preserving locks and local work'
82
92
  env DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/sync-all-branches.py" $argv
83
93
  che_notify 7 $status
84
94
  end
85
95
 
86
- function sync-all-branches-dr --description 'Delete merged branches, rebase the rest, check out new ones; branches only (preview only)'
96
+ function sync-all-branches-dr --description 'Update every branch and worktree, preserving locks and local work (preview only)'
87
97
  env DRY_RUN=true "$CHE_PYTHON" "$CHE_BIN/git/sync-all-branches.py" $argv
88
98
  che_notify 7 $status
89
99
  end
package/shell/che.zsh CHANGED
@@ -1,4 +1,4 @@
1
- # che 1.2.0 - generated file, do not edit.
1
+ # che 1.2.2 - generated file, do not edit.
2
2
  #
3
3
  # Generated from bin/commands.py by `che install`.
4
4
  # To change a wrapper, edit that manifest and run `che install` again.
@@ -65,7 +65,8 @@ _che_restore_aliases() {
65
65
 
66
66
  _che_stash_aliases che_notify che all-actions all-actions-watch \
67
67
  checkout-my-branches clean-stale-branches clean-stale-branches-dr \
68
- prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr \
68
+ hard-reset-all-branches hard-reset-all-branches-dr prune-worktrees \
69
+ prune-worktrees-dr sync-all-branches sync-all-branches-dr \
69
70
  update-from-origin update-local-branches show-codecs fix-codecs \
70
71
  fix-codecs-dr find-video-mkv-issues validate-video-files \
71
72
  scan-videos-audio-language remove-metadata rename-video-file \
@@ -132,6 +133,18 @@ clean-stale-branches-dr() {
132
133
  che_notify 7 $?
133
134
  }
134
135
 
136
+ # Check out every local branch and hard reset it to origin/<branch>
137
+ hard-reset-all-branches() {
138
+ DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/hard-reset-all-branches.py" "$@"
139
+ che_notify 4 $?
140
+ }
141
+
142
+ # Check out every local branch and hard reset it to origin/<branch> (preview only)
143
+ hard-reset-all-branches-dr() {
144
+ DRY_RUN=true "$CHE_PYTHON" "$CHE_BIN/git/hard-reset-all-branches.py" "$@"
145
+ che_notify 7 $?
146
+ }
147
+
135
148
  # Remove every linked worktree, then prune stale admin records
136
149
  prune-worktrees() {
137
150
  DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/prune-worktrees.py" "$@"
@@ -144,13 +157,13 @@ prune-worktrees-dr() {
144
157
  che_notify 7 $?
145
158
  }
146
159
 
147
- # Delete merged branches, rebase the rest, check out new ones; branches only
160
+ # Update every branch and worktree, preserving locks and local work
148
161
  sync-all-branches() {
149
162
  DRY_RUN=false "$CHE_PYTHON" "$CHE_BIN/git/sync-all-branches.py" "$@"
150
163
  che_notify 7 $?
151
164
  }
152
165
 
153
- # Delete merged branches, rebase the rest, check out new ones; branches only (preview only)
166
+ # Update every branch and worktree, preserving locks and local work (preview only)
154
167
  sync-all-branches-dr() {
155
168
  DRY_RUN=true "$CHE_PYTHON" "$CHE_BIN/git/sync-all-branches.py" "$@"
156
169
  che_notify 7 $?
@@ -1,5 +1,5 @@
1
1
  #compdef che
2
- # che 1.2.0 - generated file, do not edit.
2
+ # che 1.2.2 - generated file, do not edit.
3
3
  #
4
4
  # Generated from bin/commands.py by `che install`.
5
5
  # To change a wrapper, edit that manifest and run `che install` again.
@@ -11,6 +11,8 @@ _che_flags_for() {
11
11
  checkout-my-branches) print -r -- '--author= --limit= --help' ;;
12
12
  clean-stale-branches) print -r -- '--dry-run --protect= --help' ;;
13
13
  clean-stale-branches-dr) print -r -- '--dry-run --protect= --help' ;;
14
+ hard-reset-all-branches) print -r -- '--dry-run --force --help' ;;
15
+ hard-reset-all-branches-dr) print -r -- '--dry-run --force --help' ;;
14
16
  prune-worktrees) print -r -- '--dry-run --force --help' ;;
15
17
  prune-worktrees-dr) print -r -- '--dry-run --force --help' ;;
16
18
  sync-all-branches) print -r -- '--dry-run --author= --limit= --help' ;;
@@ -83,10 +85,12 @@ _che() {
83
85
  'checkout-my-branches:Check out recent remote branches you authored that aren'"'"'t local yet'
84
86
  'clean-stale-branches:Delete local branches whose upstream is gone'
85
87
  'clean-stale-branches-dr:Delete local branches whose upstream is gone (preview)'
88
+ 'hard-reset-all-branches:Check out every local branch and hard reset it to origin/<branch>'
89
+ 'hard-reset-all-branches-dr:Check out every local branch and hard reset it to origin/<branch> (preview)'
86
90
  'prune-worktrees:Remove every linked worktree, then prune stale admin records'
87
91
  'prune-worktrees-dr:Remove every linked worktree, then prune stale admin records (preview)'
88
- 'sync-all-branches:Delete merged branches, rebase the rest, check out new ones; branches only'
89
- 'sync-all-branches-dr:Delete merged branches, rebase the rest, check out new ones; branches only (preview)'
92
+ 'sync-all-branches:Update every branch and worktree, preserving locks and local work'
93
+ 'sync-all-branches-dr:Update every branch and worktree, preserving locks and local work (preview)'
90
94
  'update-from-origin:Alias of sync-all-branches'
91
95
  'update-local-branches:Rebase every local branch that has an upstream onto origin'
92
96
  'show-codecs:Report media files outside the Direct Play codec/container set'
@@ -143,4 +147,4 @@ _che_wrapper() {
143
147
  }
144
148
 
145
149
  compdef _che che
146
- compdef _che_wrapper all-actions all-actions-watch checkout-my-branches clean-stale-branches clean-stale-branches-dr prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr update-from-origin update-local-branches show-codecs fix-codecs fix-codecs-dr find-video-mkv-issues validate-video-files scan-videos-audio-language remove-metadata rename-video-file delete-duplicate-videos delete-duplicate-videos-dr video-list detect-green-magenta-videos find-movie-by-year largest-tv-shows delete-by-ext delete-by-ext-dr delete-empty-folders delete-empty-folders-dr delete-smb-files delete-smb-files-dr files-under-size files-under-size-dr find-largest-files make-alpha-dir compress-folders list-permission mount-all-drives eject-all-drives eject-all-drives-dr ping-nas update-brew update-brew-dr btop
150
+ compdef _che_wrapper all-actions all-actions-watch checkout-my-branches clean-stale-branches clean-stale-branches-dr hard-reset-all-branches hard-reset-all-branches-dr prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr update-from-origin update-local-branches show-codecs fix-codecs fix-codecs-dr find-video-mkv-issues validate-video-files scan-videos-audio-language remove-metadata rename-video-file delete-duplicate-videos delete-duplicate-videos-dr video-list detect-green-magenta-videos find-movie-by-year largest-tv-shows delete-by-ext delete-by-ext-dr delete-empty-folders delete-empty-folders-dr delete-smb-files delete-smb-files-dr files-under-size files-under-size-dr find-largest-files make-alpha-dir compress-folders list-permission mount-all-drives eject-all-drives eject-all-drives-dr ping-nas update-brew update-brew-dr btop
@@ -1,4 +1,4 @@
1
- # che 1.2.0 - generated file, do not edit.
1
+ # che 1.2.2 - generated file, do not edit.
2
2
  #
3
3
  # Generated from bin/commands.py by `che install`.
4
4
  # To change a wrapper, edit that manifest and run `che install` again.
@@ -11,6 +11,8 @@ _che_flags_for() {
11
11
  checkout-my-branches) echo "--author= --limit= --help" ;;
12
12
  clean-stale-branches) echo "--dry-run --protect= --help" ;;
13
13
  clean-stale-branches-dr) echo "--dry-run --protect= --help" ;;
14
+ hard-reset-all-branches) echo "--dry-run --force --help" ;;
15
+ hard-reset-all-branches-dr) echo "--dry-run --force --help" ;;
14
16
  prune-worktrees) echo "--dry-run --force --help" ;;
15
17
  prune-worktrees-dr) echo "--dry-run --force --help" ;;
16
18
  sync-all-branches) echo "--dry-run --author= --limit= --help" ;;
@@ -92,7 +94,7 @@ _che_complete() {
92
94
  local cur="${COMP_WORDS[COMP_CWORD]}"
93
95
 
94
96
  if [ "$COMP_CWORD" -eq 1 ]; then
95
- _che_reply "" < <(compgen -W "all-actions all-actions-watch checkout-my-branches clean-stale-branches clean-stale-branches-dr prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr update-from-origin update-local-branches show-codecs fix-codecs fix-codecs-dr find-video-mkv-issues validate-video-files scan-videos-audio-language remove-metadata rename-video-file delete-duplicate-videos delete-duplicate-videos-dr video-list detect-green-magenta-videos find-movie-by-year largest-tv-shows delete-by-ext delete-by-ext-dr delete-empty-folders delete-empty-folders-dr delete-smb-files delete-smb-files-dr files-under-size files-under-size-dr find-largest-files make-alpha-dir compress-folders list-permission mount-all-drives eject-all-drives eject-all-drives-dr ping-nas update-brew update-brew-dr btop install update doctor uninstall list completions" -- "$cur")
97
+ _che_reply "" < <(compgen -W "all-actions all-actions-watch checkout-my-branches clean-stale-branches clean-stale-branches-dr hard-reset-all-branches hard-reset-all-branches-dr prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr update-from-origin update-local-branches show-codecs fix-codecs fix-codecs-dr find-video-mkv-issues validate-video-files scan-videos-audio-language remove-metadata rename-video-file delete-duplicate-videos delete-duplicate-videos-dr video-list detect-green-magenta-videos find-movie-by-year largest-tv-shows delete-by-ext delete-by-ext-dr delete-empty-folders delete-empty-folders-dr delete-smb-files delete-smb-files-dr files-under-size files-under-size-dr find-largest-files make-alpha-dir compress-folders list-permission mount-all-drives eject-all-drives eject-all-drives-dr ping-nas update-brew update-brew-dr btop install update doctor uninstall list completions" -- "$cur")
96
98
  return
97
99
  fi
98
100
 
@@ -104,4 +106,4 @@ _che_complete_wrapper() {
104
106
  }
105
107
 
106
108
  complete -o nospace -F _che_complete che
107
- complete -o nospace -F _che_complete_wrapper all-actions all-actions-watch checkout-my-branches clean-stale-branches clean-stale-branches-dr prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr update-from-origin update-local-branches show-codecs fix-codecs fix-codecs-dr find-video-mkv-issues validate-video-files scan-videos-audio-language remove-metadata rename-video-file delete-duplicate-videos delete-duplicate-videos-dr video-list detect-green-magenta-videos find-movie-by-year largest-tv-shows delete-by-ext delete-by-ext-dr delete-empty-folders delete-empty-folders-dr delete-smb-files delete-smb-files-dr files-under-size files-under-size-dr find-largest-files make-alpha-dir compress-folders list-permission mount-all-drives eject-all-drives eject-all-drives-dr ping-nas update-brew update-brew-dr btop
109
+ complete -o nospace -F _che_complete_wrapper all-actions all-actions-watch checkout-my-branches clean-stale-branches clean-stale-branches-dr hard-reset-all-branches hard-reset-all-branches-dr prune-worktrees prune-worktrees-dr sync-all-branches sync-all-branches-dr update-from-origin update-local-branches show-codecs fix-codecs fix-codecs-dr find-video-mkv-issues validate-video-files scan-videos-audio-language remove-metadata rename-video-file delete-duplicate-videos delete-duplicate-videos-dr video-list detect-green-magenta-videos find-movie-by-year largest-tv-shows delete-by-ext delete-by-ext-dr delete-empty-folders delete-empty-folders-dr delete-smb-files delete-smb-files-dr files-under-size files-under-size-dr find-largest-files make-alpha-dir compress-folders list-permission mount-all-drives eject-all-drives eject-all-drives-dr ping-nas update-brew update-brew-dr btop
@@ -1,4 +1,4 @@
1
- # che 1.2.0 - generated file, do not edit.
1
+ # che 1.2.2 - generated file, do not edit.
2
2
  #
3
3
  # Generated from bin/commands.py by `che install`.
4
4
  # To change a wrapper, edit that manifest and run `che install` again.
@@ -9,10 +9,12 @@ complete -c che -n __fish_use_subcommand -a all-actions-watch -d 'Same as all-ac
9
9
  complete -c che -n __fish_use_subcommand -a checkout-my-branches -d 'Check out recent remote branches you authored that aren\'t local yet'
10
10
  complete -c che -n __fish_use_subcommand -a clean-stale-branches -d 'Delete local branches whose upstream is gone'
11
11
  complete -c che -n __fish_use_subcommand -a clean-stale-branches-dr -d 'Delete local branches whose upstream is gone (preview)'
12
+ complete -c che -n __fish_use_subcommand -a hard-reset-all-branches -d 'Check out every local branch and hard reset it to origin/<branch>'
13
+ complete -c che -n __fish_use_subcommand -a hard-reset-all-branches-dr -d 'Check out every local branch and hard reset it to origin/<branch> (preview)'
12
14
  complete -c che -n __fish_use_subcommand -a prune-worktrees -d 'Remove every linked worktree, then prune stale admin records'
13
15
  complete -c che -n __fish_use_subcommand -a prune-worktrees-dr -d 'Remove every linked worktree, then prune stale admin records (preview)'
14
- complete -c che -n __fish_use_subcommand -a sync-all-branches -d 'Delete merged branches, rebase the rest, check out new ones; branches only'
15
- complete -c che -n __fish_use_subcommand -a sync-all-branches-dr -d 'Delete merged branches, rebase the rest, check out new ones; branches only (preview)'
16
+ complete -c che -n __fish_use_subcommand -a sync-all-branches -d 'Update every branch and worktree, preserving locks and local work'
17
+ complete -c che -n __fish_use_subcommand -a sync-all-branches-dr -d 'Update every branch and worktree, preserving locks and local work (preview)'
16
18
  complete -c che -n __fish_use_subcommand -a update-from-origin -d 'Alias of sync-all-branches'
17
19
  complete -c che -n __fish_use_subcommand -a update-local-branches -d 'Rebase every local branch that has an upstream onto origin'
18
20
  complete -c che -n __fish_use_subcommand -a show-codecs -d 'Report media files outside the Direct Play codec/container set'
@@ -74,6 +76,10 @@ complete -c che -n "__fish_seen_subcommand_from clean-stale-branches" -l dry-run
74
76
  complete -c che -n "__fish_seen_subcommand_from clean-stale-branches" -l protect -r
75
77
  complete -c che -n "__fish_seen_subcommand_from clean-stale-branches-dr" -l dry-run
76
78
  complete -c che -n "__fish_seen_subcommand_from clean-stale-branches-dr" -l protect -r
79
+ complete -c che -n "__fish_seen_subcommand_from hard-reset-all-branches" -l dry-run
80
+ complete -c che -n "__fish_seen_subcommand_from hard-reset-all-branches" -l force
81
+ complete -c che -n "__fish_seen_subcommand_from hard-reset-all-branches-dr" -l dry-run
82
+ complete -c che -n "__fish_seen_subcommand_from hard-reset-all-branches-dr" -l force
77
83
  complete -c che -n "__fish_seen_subcommand_from prune-worktrees" -l dry-run
78
84
  complete -c che -n "__fish_seen_subcommand_from prune-worktrees" -l force
79
85
  complete -c che -n "__fish_seen_subcommand_from prune-worktrees-dr" -l dry-run
@@ -233,6 +239,10 @@ complete -c clean-stale-branches -l dry-run
233
239
  complete -c clean-stale-branches -l protect -r
234
240
  complete -c clean-stale-branches-dr -l dry-run
235
241
  complete -c clean-stale-branches-dr -l protect -r
242
+ complete -c hard-reset-all-branches -l dry-run
243
+ complete -c hard-reset-all-branches -l force
244
+ complete -c hard-reset-all-branches-dr -l dry-run
245
+ complete -c hard-reset-all-branches-dr -l force
236
246
  complete -c prune-worktrees -l dry-run
237
247
  complete -c prune-worktrees -l force
238
248
  complete -c prune-worktrees-dr -l dry-run