-2

Now, i am trying to find rebased commits in remote git repo using Python. I used Github api to find it. The repository is huge, there are many contributors and branches. In certain branch, finding new commits is not problem. but i can't identify which commits are newly submitted at that branch, and which commits are rebased from other branch.

If anyone know about it, please help me

5
  • 1
    git-cherry(1) and search for “cherry” in man git log. That’s all that can be said for such a general question. Commented Oct 4, 2024 at 18:37
  • 1
    Please provide enough code so others can better understand or reproduce the problem. Commented Oct 4, 2024 at 19:17
  • about "more details": you say you intend to use Github API: do you run your commands from within a clone of that repo ? (<- in that case, you can also use regular git commands) or do you have a hard constraint to go exclusively through Github API ? Commented Oct 5, 2024 at 8:50
  • 2
    someone may correct me, but I don't know of a reliable way to query "is that commit a cherry-pick of that other commit ?" through Github API. On a local git clone: you can compute and compare git patch-id for two commits. git cherry and git log --cherry-* (as suggested by @Guildenstern) use this under the hood and will give you more synthetic informations. Commented Oct 5, 2024 at 8:53
  • i posted my code bellow, i have to define is_rebased func for identify which commits are newly submitted at that branch directly, and which commits are rebased from other branch Commented Oct 5, 2024 at 19:07

1 Answer 1

0
def compare_states(current_state, previous_state):
new_branches = []
updated_branches = []
deleted_branches = []
rebased_commits = []

# Set of branch keys (repo_owner, repo_name, branch_name) for the current state
current_branch_keys = {(b['repo_owner'], b['repo_name'], b['branch_name']) for b in current_state}

for current_branch in current_state:
    repo_full_name = f"{current_branch['repo_owner']}/{current_branch['repo_name']}"
    repo = g.get_repo(repo_full_name)
    
    # Find the corresponding branch in the previous state
    previous_branch = next((b for b in previous_state 
                            if b["repo_owner"] == current_branch["repo_owner"] 
                            and b["repo_name"] == current_branch["repo_name"] 
                            and b["branch_name"] == current_branch["branch_name"]), None)
    
    # Case 1: New Branch
    if previous_branch is None:
        # Check against the default branch to detect new branches
        parent_branch = find_parent_branch(repo, current_branch)  # Implement this to find the parent
        comparison = repo.compare(parent_branch, current_branch["branch_name"])
        
        # If commits exist in the comparison, it's a new branch
        if comparison.commits:
            new_branches.append({
                "repo_owner": current_branch["repo_owner"],
                "repo_name": current_branch["repo_name"],
                "branch_name": current_branch["branch_name"],
                "commit_hash": current_branch["commit_hash"],
                "commits": convert_commits(comparison.commits)
            })
    
    # Case 2: Updated or Rebasing Branch
    else:
        # Compare the current and previous commit hashes to detect changes
        if current_branch["commit_hash"] != previous_branch["commit_hash"]:
            comparison = repo.compare(previous_branch["commit_hash"], current_branch["commit_hash"])
            updated_commits = convert_commits(comparison.commits)
            # Case 2a: Rebasing branch
            for commit in updated_commits:
                if is_rebased(commit["sha"], repo_full_name):
                    rebased_commits.append(commit)
            # Case 2b: Regular update (but not rebased)
            else:
                updated_branches.append({
                    "repo_owner": current_branch["repo_owner"],
                    "repo_name": current_branch["repo_name"],
                    "branch_name": current_branch["branch_name"],
                    "current_commit_hash": current_branch["commit_hash"],
                    "previous_commit_hash": previous_branch["commit_hash"],
                    "commits": updated_commits
                })

# Case 3: Deleted Branches
for previous_branch in previous_state:
    # If a branch in previous_state is not in current_state, it's deleted
    if (previous_branch['repo_owner'], previous_branch['repo_name'], previous_branch['branch_name']) not in current_branch_keys:
        deleted_branches.append(previous_branch)

# Return the results as 4 separate lists: new, updated, deleted, and rebased branches
return new_branches, updated_branches, deleted_branches, rebased_commits

Determines if a branch has been rebased by checking the base commit SHA.

def is_rebased(commit_sha, repo_full_name): pass # Implement the logic here

Sign up to request clarification or add additional context in comments.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.