gitpush-tool 0.3.2__tar.gz → 0.3.4__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.
- {gitpush_tool-0.3.2/gitpush_tool.egg-info → gitpush_tool-0.3.4}/PKG-INFO +1 -1
- gitpush_tool-0.3.4/gitpush/__init__.py +1 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/gitpush/cli.py +101 -2
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4/gitpush_tool.egg-info}/PKG-INFO +1 -1
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/setup.py +1 -1
- gitpush_tool-0.3.2/gitpush/__init__.py +0 -1
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/LICENSE +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/MANIFEST.in +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/README.md +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/gitpush/__doc__.py +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/gitpush_tool.egg-info/SOURCES.txt +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/gitpush_tool.egg-info/dependency_links.txt +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/gitpush_tool.egg-info/entry_points.txt +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/gitpush_tool.egg-info/top_level.txt +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/pyproject.toml +0 -0
- {gitpush_tool-0.3.2 → gitpush_tool-0.3.4}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.4"
|
|
@@ -461,21 +461,113 @@ def standard_git_push(commit_message, branch, remote, force=False, tags=False):
|
|
|
461
461
|
if force:
|
|
462
462
|
push_cmd.append("--force-with-lease")
|
|
463
463
|
print("⚠️ Using safe force push (--force-with-lease).")
|
|
464
|
-
if tags:
|
|
465
|
-
|
|
464
|
+
if tags:
|
|
465
|
+
push_cmd.append("--tags")
|
|
466
|
+
if remote and branch:
|
|
467
|
+
push_cmd.extend([remote, branch])
|
|
466
468
|
|
|
467
469
|
print(f"🚀 Executing: {' '.join(push_cmd)}")
|
|
468
470
|
subprocess.run(push_cmd, check=True)
|
|
469
471
|
print("✅ Successfully pushed changes.")
|
|
470
472
|
return True
|
|
473
|
+
|
|
471
474
|
except subprocess.CalledProcessError as e:
|
|
472
475
|
error_output = e.stderr.decode(errors='ignore').strip() if e.stderr else str(e)
|
|
476
|
+
|
|
473
477
|
if "nothing to commit" in error_output:
|
|
474
478
|
print("ℹ️ No changes to commit. Nothing to do.")
|
|
475
479
|
return True
|
|
480
|
+
|
|
481
|
+
if "non-fast-forward" in error_output.lower():
|
|
482
|
+
print("\n❗ Detected non-fast-forward issue. Attempting rebase...")
|
|
483
|
+
if attempt_rebase(remote, branch):
|
|
484
|
+
print("🔁 Retrying push after rebase...")
|
|
485
|
+
return standard_git_push(commit_message, branch, remote, force, tags)
|
|
486
|
+
else:
|
|
487
|
+
print("❌ Rebase failed. Please resolve conflicts manually and re-run the push.")
|
|
488
|
+
return False
|
|
489
|
+
|
|
476
490
|
print(f"❌ Push failed: {error_output}", file=sys.stderr)
|
|
477
491
|
return False
|
|
478
492
|
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
def has_incoming_changes(remote: str = "origin", branch: str = "main") -> bool:
|
|
496
|
+
try:
|
|
497
|
+
subprocess.run(["git", "fetch", remote], check=True, capture_output=True)
|
|
498
|
+
|
|
499
|
+
result = subprocess.run(
|
|
500
|
+
["git", "rev-list", "--left-right", "--count", f"{remote}/{branch}...{branch}"],
|
|
501
|
+
check=True, capture_output=True, text=True
|
|
502
|
+
)
|
|
503
|
+
behind_ahead = result.stdout.strip().split()
|
|
504
|
+
if len(behind_ahead) == 2:
|
|
505
|
+
behind, ahead = map(int, behind_ahead)
|
|
506
|
+
return behind > 0
|
|
507
|
+
return False
|
|
508
|
+
except subprocess.CalledProcessError:
|
|
509
|
+
return False
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
def pull_and_check_conflicts(remote: str = "origin", branch: str = "main") -> bool:
|
|
513
|
+
print("🔄 Pulling latest changes before pushing...")
|
|
514
|
+
|
|
515
|
+
try:
|
|
516
|
+
result = subprocess.run(["git", "pull", remote, branch], capture_output=True, text=True)
|
|
517
|
+
|
|
518
|
+
if "CONFLICT" in result.stdout or "CONFLICT" in result.stderr:
|
|
519
|
+
print("❗ Merge conflicts detected.")
|
|
520
|
+
return True
|
|
521
|
+
else:
|
|
522
|
+
print("✅ Pulled successfully. No conflicts.")
|
|
523
|
+
return False
|
|
524
|
+
except subprocess.CalledProcessError as e:
|
|
525
|
+
print(f"❌ Pull failed: {e.stderr or str(e)}", file=sys.stderr)
|
|
526
|
+
return True
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def show_merge_conflict_details():
|
|
531
|
+
print("\n🔍 Merge Conflict Report:\n")
|
|
532
|
+
|
|
533
|
+
try:
|
|
534
|
+
result = subprocess.run(["git", "diff", "--name-only", "--diff-filter=U"], capture_output=True, text=True, check=True)
|
|
535
|
+
conflicted_files = result.stdout.strip().splitlines()
|
|
536
|
+
|
|
537
|
+
if not conflicted_files:
|
|
538
|
+
print("✅ No merge conflicts found.")
|
|
539
|
+
return
|
|
540
|
+
|
|
541
|
+
for file in conflicted_files:
|
|
542
|
+
print(f"📄 File: {file}")
|
|
543
|
+
try:
|
|
544
|
+
with open(file, 'r', encoding='utf-8') as f:
|
|
545
|
+
lines = f.readlines()
|
|
546
|
+
for i, line in enumerate(lines):
|
|
547
|
+
if line.startswith("<<<<<<<") or line.startswith("=======") or line.startswith(">>>>>>>"):
|
|
548
|
+
marker = line.strip()
|
|
549
|
+
print(f" ⚠️ Conflict Marker ({marker}) at line {i + 1}")
|
|
550
|
+
except Exception as e:
|
|
551
|
+
print(f" ❌ Could not read file {file}: {str(e)}")
|
|
552
|
+
|
|
553
|
+
except subprocess.CalledProcessError as e:
|
|
554
|
+
print(f"❌ Could not retrieve conflicted files: {str(e)}")
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def attempt_rebase(remote: str, branch: str) -> bool:
|
|
558
|
+
print("🔁 Attempting: git pull --rebase")
|
|
559
|
+
try:
|
|
560
|
+
subprocess.run(["git", "pull", "--rebase", remote, branch], check=True)
|
|
561
|
+
print("✅ Rebase completed successfully.")
|
|
562
|
+
return True
|
|
563
|
+
except subprocess.CalledProcessError as e:
|
|
564
|
+
print(f"❌ Rebase failed: {e.stderr.decode(errors='ignore') if e.stderr else str(e)}")
|
|
565
|
+
show_merge_conflict_details()
|
|
566
|
+
return False
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
|
|
479
571
|
# --- Main Entry Point ---
|
|
480
572
|
|
|
481
573
|
def run():
|
|
@@ -532,6 +624,13 @@ def run():
|
|
|
532
624
|
print("✅ Git repository initialized successfully.")
|
|
533
625
|
|
|
534
626
|
else:
|
|
627
|
+
if has_incoming_changes(args.remote, target_branch):
|
|
628
|
+
conflicts = pull_and_check_conflicts(args.remote, target_branch)
|
|
629
|
+
if conflicts:
|
|
630
|
+
show_merge_conflict_details()
|
|
631
|
+
print("\n❌ Resolve conflicts before pushing.")
|
|
632
|
+
sys.exit(1)
|
|
633
|
+
|
|
535
634
|
if not standard_git_push(
|
|
536
635
|
args.commit,
|
|
537
636
|
target_branch,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.2"
|
|
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
|