gitpush-tool 0.3.1__tar.gz → 0.3.3__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.1/gitpush_tool.egg-info → gitpush_tool-0.3.3}/PKG-INFO +1 -1
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/README.md +1 -1
- gitpush_tool-0.3.3/gitpush/__init__.py +1 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/gitpush/cli.py +95 -1
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3/gitpush_tool.egg-info}/PKG-INFO +1 -1
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/setup.py +1 -1
- gitpush_tool-0.3.1/gitpush/__init__.py +0 -1
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/LICENSE +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/MANIFEST.in +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/gitpush/__doc__.py +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/gitpush_tool.egg-info/SOURCES.txt +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/gitpush_tool.egg-info/dependency_links.txt +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/gitpush_tool.egg-info/entry_points.txt +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/gitpush_tool.egg-info/top_level.txt +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/pyproject.toml +0 -0
- {gitpush_tool-0.3.1 → gitpush_tool-0.3.3}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.3"
|
|
@@ -317,6 +317,22 @@ def gh_authenticated():
|
|
|
317
317
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
318
318
|
return False
|
|
319
319
|
|
|
320
|
+
|
|
321
|
+
def is_local_ahead() -> bool:
|
|
322
|
+
try:
|
|
323
|
+
result = subprocess.run(
|
|
324
|
+
["git", "rev-list", "--left-right", "--count", "origin/main...HEAD"],
|
|
325
|
+
capture_output=True, text=True, check=True
|
|
326
|
+
)
|
|
327
|
+
behind_ahead = result.stdout.strip().split()
|
|
328
|
+
if len(behind_ahead) == 2:
|
|
329
|
+
behind, ahead = map(int, behind_ahead)
|
|
330
|
+
return ahead > 0
|
|
331
|
+
return False
|
|
332
|
+
except subprocess.CalledProcessError:
|
|
333
|
+
return False
|
|
334
|
+
|
|
335
|
+
|
|
320
336
|
def authenticate_with_gh():
|
|
321
337
|
"""Authenticate user with GitHub CLI"""
|
|
322
338
|
print("\n🔑 GitHub authentication required.")
|
|
@@ -437,7 +453,11 @@ def standard_git_push(commit_message, branch, remote, force=False, tags=False):
|
|
|
437
453
|
else:
|
|
438
454
|
print("ℹ️ No commit message provided. Pushing only staged changes.")
|
|
439
455
|
|
|
440
|
-
|
|
456
|
+
if is_local_ahead():
|
|
457
|
+
push_cmd = ["git", "push"]
|
|
458
|
+
else:
|
|
459
|
+
push_cmd = ["git", "push", "origin", "main"]
|
|
460
|
+
|
|
441
461
|
if force:
|
|
442
462
|
push_cmd.append("--force-with-lease")
|
|
443
463
|
print("⚠️ Using safe force push (--force-with-lease).")
|
|
@@ -456,6 +476,73 @@ def standard_git_push(commit_message, branch, remote, force=False, tags=False):
|
|
|
456
476
|
print(f"❌ Push failed: {error_output}", file=sys.stderr)
|
|
457
477
|
return False
|
|
458
478
|
|
|
479
|
+
|
|
480
|
+
def has_incoming_changes(remote: str = "origin", branch: str = "main") -> bool:
|
|
481
|
+
try:
|
|
482
|
+
subprocess.run(["git", "fetch", remote], check=True, capture_output=True)
|
|
483
|
+
|
|
484
|
+
result = subprocess.run(
|
|
485
|
+
["git", "rev-list", "--left-right", "--count", f"{remote}/{branch}...{branch}"],
|
|
486
|
+
check=True, capture_output=True, text=True
|
|
487
|
+
)
|
|
488
|
+
behind_ahead = result.stdout.strip().split()
|
|
489
|
+
if len(behind_ahead) == 2:
|
|
490
|
+
behind, ahead = map(int, behind_ahead)
|
|
491
|
+
return behind > 0
|
|
492
|
+
return False
|
|
493
|
+
except subprocess.CalledProcessError:
|
|
494
|
+
return False
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
def pull_and_check_conflicts(remote: str = "origin", branch: str = "main") -> bool:
|
|
498
|
+
print("🔄 Pulling latest changes before pushing...")
|
|
499
|
+
|
|
500
|
+
try:
|
|
501
|
+
result = subprocess.run(["git", "pull", remote, branch], capture_output=True, text=True)
|
|
502
|
+
|
|
503
|
+
if "CONFLICT" in result.stdout or "CONFLICT" in result.stderr:
|
|
504
|
+
print("❗ Merge conflicts detected.")
|
|
505
|
+
return True
|
|
506
|
+
else:
|
|
507
|
+
print("✅ Pulled successfully. No conflicts.")
|
|
508
|
+
return False
|
|
509
|
+
except subprocess.CalledProcessError as e:
|
|
510
|
+
print(f"❌ Pull failed: {e.stderr or str(e)}", file=sys.stderr)
|
|
511
|
+
return True
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
def show_merge_conflict_details():
|
|
516
|
+
print("\n🔍 Merge Conflict Report:\n")
|
|
517
|
+
|
|
518
|
+
try:
|
|
519
|
+
result = subprocess.run(["git", "diff", "--name-only", "--diff-filter=U"], capture_output=True, text=True, check=True)
|
|
520
|
+
conflicted_files = result.stdout.strip().splitlines()
|
|
521
|
+
|
|
522
|
+
if not conflicted_files:
|
|
523
|
+
print("✅ No merge conflicts found.")
|
|
524
|
+
return
|
|
525
|
+
|
|
526
|
+
for file in conflicted_files:
|
|
527
|
+
print(f"📄 File: {file}")
|
|
528
|
+
try:
|
|
529
|
+
with open(file, 'r', encoding='utf-8') as f:
|
|
530
|
+
lines = f.readlines()
|
|
531
|
+
for i, line in enumerate(lines):
|
|
532
|
+
if line.startswith("<<<<<<<") or line.startswith("=======") or line.startswith(">>>>>>>"):
|
|
533
|
+
marker = line.strip()
|
|
534
|
+
print(f" ⚠️ Conflict Marker ({marker}) at line {i + 1}")
|
|
535
|
+
except Exception as e:
|
|
536
|
+
print(f" ❌ Could not read file {file}: {str(e)}")
|
|
537
|
+
|
|
538
|
+
except subprocess.CalledProcessError as e:
|
|
539
|
+
print(f"❌ Could not retrieve conflicted files: {str(e)}")
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
|
|
459
546
|
# --- Main Entry Point ---
|
|
460
547
|
|
|
461
548
|
def run():
|
|
@@ -512,6 +599,13 @@ def run():
|
|
|
512
599
|
print("✅ Git repository initialized successfully.")
|
|
513
600
|
|
|
514
601
|
else:
|
|
602
|
+
if has_incoming_changes(args.remote, target_branch):
|
|
603
|
+
conflicts = pull_and_check_conflicts(args.remote, target_branch)
|
|
604
|
+
if conflicts:
|
|
605
|
+
show_merge_conflict_details()
|
|
606
|
+
print("\n❌ Resolve conflicts before pushing.")
|
|
607
|
+
sys.exit(1)
|
|
608
|
+
|
|
515
609
|
if not standard_git_push(
|
|
516
610
|
args.commit,
|
|
517
611
|
target_branch,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.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
|