pygitgo 1.2.1__tar.gz → 1.4.0__tar.gz
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.
- {pygitgo-1.2.1/src/pygitgo.egg-info → pygitgo-1.4.0}/PKG-INFO +31 -3
- {pygitgo-1.2.1 → pygitgo-1.4.0}/README.md +30 -2
- {pygitgo-1.2.1 → pygitgo-1.4.0}/pyproject.toml +1 -1
- pygitgo-1.4.0/src/pygitgo/commands/pull.py +43 -0
- pygitgo-1.4.0/src/pygitgo/commands/undo.py +53 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/main.py +34 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0/src/pygitgo.egg-info}/PKG-INFO +31 -3
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo.egg-info/SOURCES.txt +4 -0
- pygitgo-1.4.0/tests/test_pull.py +77 -0
- pygitgo-1.4.0/tests/test_undo.py +94 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/LICENSE +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/setup.cfg +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/__init__.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/auth/__init__.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/auth/account.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/auth/manager.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/auth/ssh_utils.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/commands/__init__.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/commands/git_operations.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/commands/jump.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/commands/state.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/exceptions.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/utils/__init__.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/utils/colors.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/utils/config.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/utils/executor.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/utils/platform_utils.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo/utils/setup.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo.egg-info/dependency_links.txt +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo.egg-info/entry_points.txt +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo.egg-info/requires.txt +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/src/pygitgo.egg-info/top_level.txt +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_config.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_git_operations.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_jump.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_main.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_platform.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_setup.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_state.py +0 -0
- {pygitgo-1.2.1 → pygitgo-1.4.0}/tests/test_url_validator.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygitgo
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: GitGo CLI - Your Fast Git Companion. Simplifies git push, link, stash, and user management.
|
|
5
5
|
Author: Huerte
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -40,7 +40,7 @@ Dynamic: license-file
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
GitGo wraps your most repetitive
|
|
43
|
+
GitGo wraps your most repetitive git commands into short ones you can actually remember. It covers init, add, commit, push, branch, and stash. It also handles the things most tools skip like automatic SSH setup, HTTPS to SSH conversion, and a simple stash interface called state management.
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
# Instead of this:
|
|
@@ -76,6 +76,7 @@ gitgo link https://github.com/username/repo.git "init"
|
|
|
76
76
|
GitGo provides a CLI environment designed for faster and simpler Git workflows. Built to be intuitive, fast, and frictionless.
|
|
77
77
|
|
|
78
78
|
- **Simplified Git Operations:** Replaces chained commands with single intuitive commands for linking, pushing, and stashing.
|
|
79
|
+
- **Easy Undo Operations:** Safely undo commits, un-queue files, or wipe local changes without any complex Git jargon.
|
|
79
80
|
- **Smart Branch Hopping:** Safely traverse branches with `jump`. Auto-stashes messy code and prevents merge conflict disasters with a Try-And-Revert safety engine.
|
|
80
81
|
- **State Management:** A human-readable interface over `git stash`. States are named and listed by index so you never have to remember cryptic stash references.
|
|
81
82
|
- **Custom Defaults:** Save your preferred branch name and commit message locally so you never have to type them again.
|
|
@@ -147,7 +148,15 @@ Jump to a different branch without worrying about your uncommitted changes. GitG
|
|
|
147
148
|
gitgo jump feature/new-login
|
|
148
149
|
```
|
|
149
150
|
|
|
150
|
-
### 5.
|
|
151
|
+
### 5. Safely Undo Mistakes
|
|
152
|
+
Easily fix common mistakes without losing work or needing to search for Git commands.
|
|
153
|
+
```bash
|
|
154
|
+
gitgo undo commit # Undo the last commit (files stay safe)
|
|
155
|
+
gitgo undo add # Un-queue files (undo git add)
|
|
156
|
+
gitgo undo changes # DANGER: permanently wipe all unsaved edits
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 6. Save Your Work-in-Progress
|
|
151
160
|
```bash
|
|
152
161
|
gitgo state save "halfway through refactor"
|
|
153
162
|
gitgo state list
|
|
@@ -184,6 +193,15 @@ gitgo push -n [branch] [message] # create new branch first
|
|
|
184
193
|
|
|
185
194
|
If there are no new changes but unpushed commits exist, GitGo detects this and pushes without creating an empty commit.
|
|
186
195
|
|
|
196
|
+
### `gitgo pull`
|
|
197
|
+
|
|
198
|
+
Safely downloads updates from the remote server. It automatically stashes your messy code, pulls the updates cleanly underneath using a rebase, and then instantly puts your code back exactly how it was.
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
gitgo pull # Safely pull updates for your current branch
|
|
202
|
+
gitgo pull <branch> # Safely pull updates from a specific branch
|
|
203
|
+
```
|
|
204
|
+
|
|
187
205
|
### `gitgo link`
|
|
188
206
|
|
|
189
207
|
Initializes a Git repository in the current directory, connects it to a remote, and pushes. Handles already-initialized repos gracefully and pulls unrelated histories.
|
|
@@ -200,6 +218,16 @@ Safely switches branches without losing uncommitted progress. Auto-stashes, jump
|
|
|
200
218
|
gitgo jump <branch>
|
|
201
219
|
```
|
|
202
220
|
|
|
221
|
+
### `gitgo undo`
|
|
222
|
+
|
|
223
|
+
Safely undo recent actions and mistakes using simple, human-readable commands.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
gitgo undo commit # Undo your last commit without losing files
|
|
227
|
+
gitgo undo add # Un-queue files (remove them from being ready to commit)
|
|
228
|
+
gitgo undo changes # Permanently wipe all new files and local edits
|
|
229
|
+
```
|
|
230
|
+
|
|
203
231
|
### `gitgo state`
|
|
204
232
|
|
|
205
233
|
A human-readable interface over `git stash`.
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
GitGo wraps your most repetitive
|
|
20
|
+
GitGo wraps your most repetitive git commands into short ones you can actually remember. It covers init, add, commit, push, branch, and stash. It also handles the things most tools skip like automatic SSH setup, HTTPS to SSH conversion, and a simple stash interface called state management.
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
# Instead of this:
|
|
@@ -53,6 +53,7 @@ gitgo link https://github.com/username/repo.git "init"
|
|
|
53
53
|
GitGo provides a CLI environment designed for faster and simpler Git workflows. Built to be intuitive, fast, and frictionless.
|
|
54
54
|
|
|
55
55
|
- **Simplified Git Operations:** Replaces chained commands with single intuitive commands for linking, pushing, and stashing.
|
|
56
|
+
- **Easy Undo Operations:** Safely undo commits, un-queue files, or wipe local changes without any complex Git jargon.
|
|
56
57
|
- **Smart Branch Hopping:** Safely traverse branches with `jump`. Auto-stashes messy code and prevents merge conflict disasters with a Try-And-Revert safety engine.
|
|
57
58
|
- **State Management:** A human-readable interface over `git stash`. States are named and listed by index so you never have to remember cryptic stash references.
|
|
58
59
|
- **Custom Defaults:** Save your preferred branch name and commit message locally so you never have to type them again.
|
|
@@ -124,7 +125,15 @@ Jump to a different branch without worrying about your uncommitted changes. GitG
|
|
|
124
125
|
gitgo jump feature/new-login
|
|
125
126
|
```
|
|
126
127
|
|
|
127
|
-
### 5.
|
|
128
|
+
### 5. Safely Undo Mistakes
|
|
129
|
+
Easily fix common mistakes without losing work or needing to search for Git commands.
|
|
130
|
+
```bash
|
|
131
|
+
gitgo undo commit # Undo the last commit (files stay safe)
|
|
132
|
+
gitgo undo add # Un-queue files (undo git add)
|
|
133
|
+
gitgo undo changes # DANGER: permanently wipe all unsaved edits
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 6. Save Your Work-in-Progress
|
|
128
137
|
```bash
|
|
129
138
|
gitgo state save "halfway through refactor"
|
|
130
139
|
gitgo state list
|
|
@@ -161,6 +170,15 @@ gitgo push -n [branch] [message] # create new branch first
|
|
|
161
170
|
|
|
162
171
|
If there are no new changes but unpushed commits exist, GitGo detects this and pushes without creating an empty commit.
|
|
163
172
|
|
|
173
|
+
### `gitgo pull`
|
|
174
|
+
|
|
175
|
+
Safely downloads updates from the remote server. It automatically stashes your messy code, pulls the updates cleanly underneath using a rebase, and then instantly puts your code back exactly how it was.
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
gitgo pull # Safely pull updates for your current branch
|
|
179
|
+
gitgo pull <branch> # Safely pull updates from a specific branch
|
|
180
|
+
```
|
|
181
|
+
|
|
164
182
|
### `gitgo link`
|
|
165
183
|
|
|
166
184
|
Initializes a Git repository in the current directory, connects it to a remote, and pushes. Handles already-initialized repos gracefully and pulls unrelated histories.
|
|
@@ -177,6 +195,16 @@ Safely switches branches without losing uncommitted progress. Auto-stashes, jump
|
|
|
177
195
|
gitgo jump <branch>
|
|
178
196
|
```
|
|
179
197
|
|
|
198
|
+
### `gitgo undo`
|
|
199
|
+
|
|
200
|
+
Safely undo recent actions and mistakes using simple, human-readable commands.
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
gitgo undo commit # Undo your last commit without losing files
|
|
204
|
+
gitgo undo add # Un-queue files (remove them from being ready to commit)
|
|
205
|
+
gitgo undo changes # Permanently wipe all new files and local edits
|
|
206
|
+
```
|
|
207
|
+
|
|
180
208
|
### `gitgo state`
|
|
181
209
|
|
|
182
210
|
A human-readable interface over `git stash`.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pygitgo"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.4.0"
|
|
8
8
|
description = "GitGo CLI - Your Fast Git Companion. Simplifies git push, link, stash, and user management."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "GPL-3.0-or-later"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from pygitgo.utils.colors import success, warning, error, info
|
|
2
|
+
from pygitgo.utils.executor import run_command
|
|
3
|
+
from pygitgo.exceptions import GitCommandError
|
|
4
|
+
from pygitgo.commands.git_operations import get_current_branch
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
def pull_operation(args):
|
|
9
|
+
branch = args.branch
|
|
10
|
+
|
|
11
|
+
if not branch:
|
|
12
|
+
branch = get_current_branch()
|
|
13
|
+
info(f"No branch provided. Pulling latest updates for '{branch}'...\n")
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
remote_refs = run_command(["git", "ls-remote", "--heads", "origin", branch], allow_fail=True)
|
|
17
|
+
if isinstance(remote_refs, subprocess.CalledProcessError) or not remote_refs.strip():
|
|
18
|
+
error(f"\nFailed! The branch '{branch}' does not exist on the remote server.")
|
|
19
|
+
warning("You might need to push your local branch first.\n")
|
|
20
|
+
sys.exit(1)
|
|
21
|
+
|
|
22
|
+
run_command(
|
|
23
|
+
["git", "pull", "--rebase", "--autostash", "origin", branch],
|
|
24
|
+
loading_msg=f"Downloading latest updates for '{branch}' (auto-saving your code)..."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
success(f"\nSuccess! Your project is now up to date with '{branch}'.\n")
|
|
28
|
+
|
|
29
|
+
except GitCommandError as e:
|
|
30
|
+
error_msg = str(e).lower()
|
|
31
|
+
if "conflict" in error_msg or "rebase in progress" in error_msg:
|
|
32
|
+
error("\nMERGE CONFLICT DETECTED!")
|
|
33
|
+
warning("Your local code clashes with the new code downloaded from the server.\n")
|
|
34
|
+
info("1. Open your code editor down below.")
|
|
35
|
+
info("2. Fix the red conflict lines in your files.")
|
|
36
|
+
info("3. Save the files.")
|
|
37
|
+
info("4. Run this command to finish: git rebase --continue\n")
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
else:
|
|
40
|
+
error("\nFailed to pull updates from the server!")
|
|
41
|
+
error("Please check your internet connection and try again.")
|
|
42
|
+
error(f"Details: {e}\n")
|
|
43
|
+
sys.exit(1)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from pygitgo.utils.colors import success, warning, error, info
|
|
2
|
+
from pygitgo.exceptions import GitCommandError
|
|
3
|
+
from pygitgo.utils.executor import run_command
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def undo_commit():
|
|
8
|
+
try:
|
|
9
|
+
run_command(["git", "reset", "--soft", "HEAD~"])
|
|
10
|
+
success("\nSuccess! Your last commit is undone. Your files are safe.\n")
|
|
11
|
+
except GitCommandError as e:
|
|
12
|
+
error("\nFailed! You might not have any previous commits to undo yet.")
|
|
13
|
+
error(f"Details: {e}\n")
|
|
14
|
+
sys.exit(1)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def undo_add():
|
|
18
|
+
try:
|
|
19
|
+
run_command(["git", "reset", "HEAD"])
|
|
20
|
+
success("\nSuccess! Files are no longer ready to commit.\n")
|
|
21
|
+
except GitCommandError as e:
|
|
22
|
+
error(f"\n{e}\n")
|
|
23
|
+
sys.exit(1)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def undo_changes():
|
|
27
|
+
warning("\nDANGER: This will permanently delete all your new edits and new files!")
|
|
28
|
+
confirm = input("Are you sure you want to throw away all changes? (y/n): ")
|
|
29
|
+
if confirm.lower() != "y":
|
|
30
|
+
info("\nCanceled. Your files are safe.\n")
|
|
31
|
+
return
|
|
32
|
+
try:
|
|
33
|
+
run_command(["git", "reset", "--hard", "HEAD"], loading_msg="Throwing away edits...")
|
|
34
|
+
run_command(["git", "clean", "-fd"], loading_msg="Removing new files...")
|
|
35
|
+
|
|
36
|
+
success("\nSuccess! All changes are completely gone. You have a clean start.\n")
|
|
37
|
+
except GitCommandError as e:
|
|
38
|
+
error(f"\n{e}\n")
|
|
39
|
+
sys.exit(1)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def undo_operations(args):
|
|
43
|
+
action = args.action
|
|
44
|
+
|
|
45
|
+
if action == "commit":
|
|
46
|
+
undo_commit()
|
|
47
|
+
elif action == "add":
|
|
48
|
+
undo_add()
|
|
49
|
+
elif action == "changes":
|
|
50
|
+
undo_changes()
|
|
51
|
+
else:
|
|
52
|
+
error(f"\nUnknown undo operation: {action}\n")
|
|
53
|
+
sys.exit(1)
|
|
@@ -7,6 +7,8 @@ from pygitgo.utils.config import get_config, config_operation
|
|
|
7
7
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
8
8
|
from pygitgo.utils.setup import ensure_first_run_setup
|
|
9
9
|
from pygitgo.commands.state import state_operations
|
|
10
|
+
from pygitgo.commands.undo import undo_operations
|
|
11
|
+
from pygitgo.commands.pull import pull_operation
|
|
10
12
|
from pygitgo.commands.jump import jump_operation
|
|
11
13
|
from pygitgo.utils.executor import run_command
|
|
12
14
|
from pygitgo.auth.manager import login, logout
|
|
@@ -185,6 +187,7 @@ def get_version():
|
|
|
185
187
|
except Exception:
|
|
186
188
|
return "dev"
|
|
187
189
|
|
|
190
|
+
|
|
188
191
|
def main():
|
|
189
192
|
parser = argparse.ArgumentParser(
|
|
190
193
|
prog='gitgo',
|
|
@@ -264,6 +267,33 @@ def main():
|
|
|
264
267
|
config_parser.add_argument("key", choices=["default-branch", "default-message"], help="The setting to change")
|
|
265
268
|
config_parser.add_argument("value", nargs="?", help="The new value (required for 'set')")
|
|
266
269
|
|
|
270
|
+
undo_parser = subparsers.add_parser("undo",
|
|
271
|
+
help="Safely undo mistakes",
|
|
272
|
+
epilog=(
|
|
273
|
+
"Examples:\n"
|
|
274
|
+
" gitgo undo commit Undo your last commit (your files are safe)\n"
|
|
275
|
+
" gitgo undo add Undo 'git add' (files are no longer ready to commit)\n"
|
|
276
|
+
" gitgo undo changes DANGER: Throw away all new changes and start fresh"
|
|
277
|
+
),
|
|
278
|
+
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
279
|
+
)
|
|
280
|
+
undo_parser.add_argument(
|
|
281
|
+
"action",
|
|
282
|
+
choices=["commit", "add", "changes"],
|
|
283
|
+
help="What to undo: 'commit', 'add', or 'changes'"
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
pull_parser = subparsers.add_parser("pull",
|
|
287
|
+
help="Safely pull the latest code without losing your changes",
|
|
288
|
+
epilog=(
|
|
289
|
+
"Examples:\n"
|
|
290
|
+
" gitgo pull Safely pull updates for your current branch\n"
|
|
291
|
+
" gitgo pull main Safely pull updates from the 'main' branch\n"
|
|
292
|
+
),
|
|
293
|
+
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
294
|
+
)
|
|
295
|
+
pull_parser.add_argument("branch", nargs="?", default=None, help="The branch to pull from (default is your current branch)")
|
|
296
|
+
|
|
267
297
|
args = parser.parse_args()
|
|
268
298
|
|
|
269
299
|
if args.ready:
|
|
@@ -289,6 +319,10 @@ def main():
|
|
|
289
319
|
user_management(args)
|
|
290
320
|
elif args.command == "config":
|
|
291
321
|
config_operation(args)
|
|
322
|
+
elif args.command == "undo":
|
|
323
|
+
undo_operations(args)
|
|
324
|
+
elif args.command == "pull":
|
|
325
|
+
pull_operation(args)
|
|
292
326
|
except GitGoError as e:
|
|
293
327
|
error(f"\n{e}\n")
|
|
294
328
|
sys.exit(1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygitgo
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: GitGo CLI - Your Fast Git Companion. Simplifies git push, link, stash, and user management.
|
|
5
5
|
Author: Huerte
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -40,7 +40,7 @@ Dynamic: license-file
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
GitGo wraps your most repetitive
|
|
43
|
+
GitGo wraps your most repetitive git commands into short ones you can actually remember. It covers init, add, commit, push, branch, and stash. It also handles the things most tools skip like automatic SSH setup, HTTPS to SSH conversion, and a simple stash interface called state management.
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
# Instead of this:
|
|
@@ -76,6 +76,7 @@ gitgo link https://github.com/username/repo.git "init"
|
|
|
76
76
|
GitGo provides a CLI environment designed for faster and simpler Git workflows. Built to be intuitive, fast, and frictionless.
|
|
77
77
|
|
|
78
78
|
- **Simplified Git Operations:** Replaces chained commands with single intuitive commands for linking, pushing, and stashing.
|
|
79
|
+
- **Easy Undo Operations:** Safely undo commits, un-queue files, or wipe local changes without any complex Git jargon.
|
|
79
80
|
- **Smart Branch Hopping:** Safely traverse branches with `jump`. Auto-stashes messy code and prevents merge conflict disasters with a Try-And-Revert safety engine.
|
|
80
81
|
- **State Management:** A human-readable interface over `git stash`. States are named and listed by index so you never have to remember cryptic stash references.
|
|
81
82
|
- **Custom Defaults:** Save your preferred branch name and commit message locally so you never have to type them again.
|
|
@@ -147,7 +148,15 @@ Jump to a different branch without worrying about your uncommitted changes. GitG
|
|
|
147
148
|
gitgo jump feature/new-login
|
|
148
149
|
```
|
|
149
150
|
|
|
150
|
-
### 5.
|
|
151
|
+
### 5. Safely Undo Mistakes
|
|
152
|
+
Easily fix common mistakes without losing work or needing to search for Git commands.
|
|
153
|
+
```bash
|
|
154
|
+
gitgo undo commit # Undo the last commit (files stay safe)
|
|
155
|
+
gitgo undo add # Un-queue files (undo git add)
|
|
156
|
+
gitgo undo changes # DANGER: permanently wipe all unsaved edits
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 6. Save Your Work-in-Progress
|
|
151
160
|
```bash
|
|
152
161
|
gitgo state save "halfway through refactor"
|
|
153
162
|
gitgo state list
|
|
@@ -184,6 +193,15 @@ gitgo push -n [branch] [message] # create new branch first
|
|
|
184
193
|
|
|
185
194
|
If there are no new changes but unpushed commits exist, GitGo detects this and pushes without creating an empty commit.
|
|
186
195
|
|
|
196
|
+
### `gitgo pull`
|
|
197
|
+
|
|
198
|
+
Safely downloads updates from the remote server. It automatically stashes your messy code, pulls the updates cleanly underneath using a rebase, and then instantly puts your code back exactly how it was.
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
gitgo pull # Safely pull updates for your current branch
|
|
202
|
+
gitgo pull <branch> # Safely pull updates from a specific branch
|
|
203
|
+
```
|
|
204
|
+
|
|
187
205
|
### `gitgo link`
|
|
188
206
|
|
|
189
207
|
Initializes a Git repository in the current directory, connects it to a remote, and pushes. Handles already-initialized repos gracefully and pulls unrelated histories.
|
|
@@ -200,6 +218,16 @@ Safely switches branches without losing uncommitted progress. Auto-stashes, jump
|
|
|
200
218
|
gitgo jump <branch>
|
|
201
219
|
```
|
|
202
220
|
|
|
221
|
+
### `gitgo undo`
|
|
222
|
+
|
|
223
|
+
Safely undo recent actions and mistakes using simple, human-readable commands.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
gitgo undo commit # Undo your last commit without losing files
|
|
227
|
+
gitgo undo add # Un-queue files (remove them from being ready to commit)
|
|
228
|
+
gitgo undo changes # Permanently wipe all new files and local edits
|
|
229
|
+
```
|
|
230
|
+
|
|
203
231
|
### `gitgo state`
|
|
204
232
|
|
|
205
233
|
A human-readable interface over `git stash`.
|
|
@@ -17,7 +17,9 @@ src/pygitgo/auth/ssh_utils.py
|
|
|
17
17
|
src/pygitgo/commands/__init__.py
|
|
18
18
|
src/pygitgo/commands/git_operations.py
|
|
19
19
|
src/pygitgo/commands/jump.py
|
|
20
|
+
src/pygitgo/commands/pull.py
|
|
20
21
|
src/pygitgo/commands/state.py
|
|
22
|
+
src/pygitgo/commands/undo.py
|
|
21
23
|
src/pygitgo/utils/__init__.py
|
|
22
24
|
src/pygitgo/utils/colors.py
|
|
23
25
|
src/pygitgo/utils/config.py
|
|
@@ -29,6 +31,8 @@ tests/test_git_operations.py
|
|
|
29
31
|
tests/test_jump.py
|
|
30
32
|
tests/test_main.py
|
|
31
33
|
tests/test_platform.py
|
|
34
|
+
tests/test_pull.py
|
|
32
35
|
tests/test_setup.py
|
|
33
36
|
tests/test_state.py
|
|
37
|
+
tests/test_undo.py
|
|
34
38
|
tests/test_url_validator.py
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest.mock import patch, MagicMock
|
|
3
|
+
from pygitgo.commands.pull import pull_operation
|
|
4
|
+
from pygitgo.exceptions import GitCommandError
|
|
5
|
+
from argparse import Namespace
|
|
6
|
+
import subprocess
|
|
7
|
+
|
|
8
|
+
@patch("pygitgo.commands.pull.run_command")
|
|
9
|
+
@patch("pygitgo.commands.pull.success")
|
|
10
|
+
@patch("pygitgo.commands.pull.get_current_branch", return_value="main")
|
|
11
|
+
def test_pull_operation_success_no_branch(mock_get_branch, mock_success, mock_run_command):
|
|
12
|
+
mock_run_command.side_effect = [
|
|
13
|
+
"1234567890abcdef",
|
|
14
|
+
None
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
args = Namespace(branch=None)
|
|
18
|
+
pull_operation(args)
|
|
19
|
+
|
|
20
|
+
assert mock_run_command.call_count == 2
|
|
21
|
+
mock_run_command.assert_any_call(["git", "ls-remote", "--heads", "origin", "main"], allow_fail=True)
|
|
22
|
+
mock_run_command.assert_any_call(
|
|
23
|
+
["git", "pull", "--rebase", "--autostash", "origin", "main"],
|
|
24
|
+
loading_msg="Downloading latest updates for 'main' (auto-saving your code)..."
|
|
25
|
+
)
|
|
26
|
+
mock_success.assert_called_once()
|
|
27
|
+
|
|
28
|
+
@patch("pygitgo.commands.pull.run_command")
|
|
29
|
+
@patch("pygitgo.commands.pull.success")
|
|
30
|
+
def test_pull_operation_success_with_branch(mock_success, mock_run_command):
|
|
31
|
+
mock_run_command.side_effect = [
|
|
32
|
+
"1234567890abcdef",
|
|
33
|
+
None
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
args = Namespace(branch="feature/test")
|
|
37
|
+
pull_operation(args)
|
|
38
|
+
|
|
39
|
+
assert mock_run_command.call_count == 2
|
|
40
|
+
mock_run_command.assert_any_call(["git", "ls-remote", "--heads", "origin", "feature/test"], allow_fail=True)
|
|
41
|
+
mock_run_command.assert_any_call(
|
|
42
|
+
["git", "pull", "--rebase", "--autostash", "origin", "feature/test"],
|
|
43
|
+
loading_msg="Downloading latest updates for 'feature/test' (auto-saving your code)..."
|
|
44
|
+
)
|
|
45
|
+
mock_success.assert_called_once()
|
|
46
|
+
|
|
47
|
+
@patch("pygitgo.commands.pull.sys.exit")
|
|
48
|
+
@patch("pygitgo.commands.pull.error")
|
|
49
|
+
@patch("pygitgo.commands.pull.run_command")
|
|
50
|
+
def test_pull_operation_branch_not_found(mock_run_command, mock_error, mock_exit):
|
|
51
|
+
mock_run_command.return_value = subprocess.CalledProcessError(128, ["git", "ls-remote"])
|
|
52
|
+
|
|
53
|
+
args = Namespace(branch="does-not-exist")
|
|
54
|
+
pull_operation(args)
|
|
55
|
+
|
|
56
|
+
mock_exit.assert_called_once_with(1)
|
|
57
|
+
mock_error.assert_called()
|
|
58
|
+
|
|
59
|
+
@patch("pygitgo.commands.pull.sys.exit")
|
|
60
|
+
@patch("pygitgo.commands.pull.error")
|
|
61
|
+
@patch("pygitgo.commands.pull.run_command")
|
|
62
|
+
def test_pull_operation_merge_conflict(mock_run_command, mock_error, mock_exit):
|
|
63
|
+
conflict_err = GitCommandError(["git", "pull"], stderr="merge conflict in file.py")
|
|
64
|
+
|
|
65
|
+
def side_effect_fn(*args, **kwargs):
|
|
66
|
+
cmd = args[0]
|
|
67
|
+
if cmd[1] == "ls-remote":
|
|
68
|
+
return "1234567890abcdef"
|
|
69
|
+
raise conflict_err
|
|
70
|
+
|
|
71
|
+
mock_run_command.side_effect = side_effect_fn
|
|
72
|
+
|
|
73
|
+
args = Namespace(branch="main")
|
|
74
|
+
pull_operation(args)
|
|
75
|
+
|
|
76
|
+
mock_exit.assert_called_once_with(1)
|
|
77
|
+
mock_error.assert_any_call("\nMERGE CONFLICT DETECTED!")
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest.mock import patch, MagicMock
|
|
3
|
+
from pygitgo.commands.undo import undo_commit, undo_add, undo_changes, undo_operations
|
|
4
|
+
from pygitgo.exceptions import GitCommandError
|
|
5
|
+
from argparse import Namespace
|
|
6
|
+
|
|
7
|
+
@patch("pygitgo.commands.undo.run_command")
|
|
8
|
+
@patch("pygitgo.commands.undo.success")
|
|
9
|
+
def test_undo_commit_success(mock_success, mock_run_command):
|
|
10
|
+
undo_commit()
|
|
11
|
+
mock_run_command.assert_called_once_with(["git", "reset", "--soft", "HEAD~"])
|
|
12
|
+
mock_success.assert_called_once()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@patch("pygitgo.commands.undo.sys.exit")
|
|
16
|
+
@patch("pygitgo.commands.undo.error")
|
|
17
|
+
@patch("pygitgo.commands.undo.run_command")
|
|
18
|
+
def test_undo_commit_failure(mock_run_command, mock_error, mock_exit):
|
|
19
|
+
mock_run_command.side_effect = GitCommandError(["git", "reset", "--soft", "HEAD~"])
|
|
20
|
+
undo_commit()
|
|
21
|
+
mock_run_command.assert_called_once()
|
|
22
|
+
assert mock_error.call_count == 2
|
|
23
|
+
mock_exit.assert_called_once_with(1)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@patch("pygitgo.commands.undo.run_command")
|
|
27
|
+
@patch("pygitgo.commands.undo.success")
|
|
28
|
+
def test_undo_add_success(mock_success, mock_run_command):
|
|
29
|
+
undo_add()
|
|
30
|
+
mock_run_command.assert_called_once_with(["git", "reset", "HEAD"])
|
|
31
|
+
mock_success.assert_called_once()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@patch("pygitgo.commands.undo.sys.exit")
|
|
35
|
+
@patch("pygitgo.commands.undo.error")
|
|
36
|
+
@patch("pygitgo.commands.undo.run_command")
|
|
37
|
+
def test_undo_add_failure(mock_run_command, mock_error, mock_exit):
|
|
38
|
+
mock_run_command.side_effect = GitCommandError(["git", "reset", "HEAD"])
|
|
39
|
+
undo_add()
|
|
40
|
+
mock_run_command.assert_called_once()
|
|
41
|
+
mock_error.assert_called_once()
|
|
42
|
+
mock_exit.assert_called_once_with(1)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@patch("pygitgo.commands.undo.run_command")
|
|
46
|
+
@patch("pygitgo.commands.undo.success")
|
|
47
|
+
@patch("pygitgo.commands.undo.input", return_value="y")
|
|
48
|
+
def test_undo_changes_success(mock_input, mock_success, mock_run_command):
|
|
49
|
+
undo_changes()
|
|
50
|
+
mock_input.assert_called_once()
|
|
51
|
+
assert mock_run_command.call_count == 2
|
|
52
|
+
mock_run_command.assert_any_call(["git", "reset", "--hard", "HEAD"], loading_msg="Throwing away edits...")
|
|
53
|
+
mock_run_command.assert_any_call(["git", "clean", "-fd"], loading_msg="Removing new files...")
|
|
54
|
+
mock_success.assert_called_once()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@patch("pygitgo.commands.undo.run_command")
|
|
58
|
+
@patch("pygitgo.commands.undo.info")
|
|
59
|
+
@patch("pygitgo.commands.undo.input", return_value="n")
|
|
60
|
+
def test_undo_changes_abort(mock_input, mock_info, mock_run_command):
|
|
61
|
+
undo_changes()
|
|
62
|
+
mock_input.assert_called_once()
|
|
63
|
+
mock_info.assert_called_once()
|
|
64
|
+
mock_run_command.assert_not_called()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@patch("pygitgo.commands.undo.undo_commit")
|
|
68
|
+
def test_undo_operations_commit(mock_undo_commit):
|
|
69
|
+
args = Namespace(action="commit")
|
|
70
|
+
undo_operations(args)
|
|
71
|
+
mock_undo_commit.assert_called_once()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@patch("pygitgo.commands.undo.undo_add")
|
|
75
|
+
def test_undo_operations_add(mock_undo_add):
|
|
76
|
+
args = Namespace(action="add")
|
|
77
|
+
undo_operations(args)
|
|
78
|
+
mock_undo_add.assert_called_once()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@patch("pygitgo.commands.undo.undo_changes")
|
|
82
|
+
def test_undo_operations_changes(mock_undo_changes):
|
|
83
|
+
args = Namespace(action="changes")
|
|
84
|
+
undo_operations(args)
|
|
85
|
+
mock_undo_changes.assert_called_once()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@patch("pygitgo.commands.undo.sys.exit")
|
|
89
|
+
@patch("pygitgo.commands.undo.error")
|
|
90
|
+
def test_undo_operations_invalid(mock_error, mock_exit):
|
|
91
|
+
args = Namespace(action="invalid")
|
|
92
|
+
undo_operations(args)
|
|
93
|
+
mock_error.assert_called_once()
|
|
94
|
+
mock_exit.assert_called_once_with(1)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|