I have a source repository in gitlab and by forking that I've created destination repository. Now if in the source repository new commits are pushed I want to copy those commits in the destination repository. To automate this process I've created a Python script which uses the python-gitlab library.
I am able to create commits in the destination repo if the commit in the source repo contains some content changes in files or the file is deleted, but the script doesn't work if the files is renamed.
def copying_commit():
tag = source_project.tags.get('v0.0.8')
commit_sha = tag.commit['id']
source_commit = source_project.commits.get(commit_sha)
destination_project = gl.projects.get(project_id)
source_branch = 'sub_dev'
# Initialize a list to store actions for the commit
commit_actions = []
# Iterate through file changes and accumulate actions
for file_change in source_commit.diff():
print(file_change)
print(file_change['new_path'])
print(file_change['old_path'])
if file_change['deleted_file']:
action_type = 'delete'
elif file_change['new_file']:
action_type = 'create'
else:
action_type = 'update'
commit_actions.append({
'action': action_type,
'file_path': file_change['new_path'] if action_type != 'delete' else file_change['old_path'],
'content': source_project.files.raw(file_path=file_change['new_path'],
ref=source_branch_info.name).decode('UTF-8')
if action_type != 'delete' else None
})
commit = destination_project.commits.create({
'branch': 'sub_dev',
'commit_message': f' v0.0.8 Merge changes from{source_project.web_url} {source_branch}',
'actions': commit_actions
})
destination_project.tags.create({
'tag_name': 'v0.0.8',
'ref': commit.id,
'message': f'Tag v0.0.8 for commit {commit.id}'
})
When the source commit contains any renamed it throws an error as follows:
gitlab.exceptions.GitlabCreateError: 400: A file with this name doesn't exist
The issue is solved,I just added one more condition i.e if the file is renamed then set the action_type="move"
# Initialize a list to store actions for the commit
commit_actions = []
# Iterate through file changes and accumulate actions
for file_change in source_commit.diff():
if file_change['deleted_file']:
action_type = 'delete'
elif file_change['new_file']:
action_type = 'create'
elif file_change['renamed_file']:
action_type = 'move'
else:
action_type = 'update'
if action_type == 'move':
commit_actions.append({
'action': action_type,
'file_path': file_change['new_path'] if action_type != 'delete' else file_change['old_path'],
'content': source_project.files.raw(file_path=file_change['new_path'],
ref=source_branch_info.name).decode('UTF-8'),
'previous_path': file_change['old_path']
if action_type != 'delete' else None
})
else:
commit_actions.append({
'action': action_type,
'file_path': file_change['new_path'] if action_type != 'delete' else file_change['old_path'],
'content': source_project.files.raw(file_path=file_change['new_path'],
ref=source_branch_info.name).decode('UTF-8')
if action_type != 'delete' else None
})
commit = destination_project.commits.create({
'branch': 'sub_dev',
'commit_message': f' {version} Merge changes from{source_project.web_url} {source_branch}',
'actions': commit_actions
})
destination_project.tags.create({
'tag_name': version, # Replace with the desired tag name
'ref': commit.id,
'message': f'Tag {version} for commit {commit.id}'
})