Merge pull request #13 from chad-loder/fix-file-operations-parameters

Fix GitLab API parameter handling in create_or_update_file
This commit is contained in:
zereight
2025-03-18 15:51:31 +09:00
committed by GitHub
2 changed files with 44 additions and 6 deletions

View File

@ -401,7 +401,9 @@ async function createOrUpdateFile(
content: string, content: string,
commitMessage: string, commitMessage: string,
branch: string, branch: string,
previousPath?: string previousPath?: string,
last_commit_id?: string,
commit_id?: string
): Promise<GitLabCreateUpdateFileResponse> { ): Promise<GitLabCreateUpdateFileResponse> {
const encodedPath = encodeURIComponent(filePath); const encodedPath = encodeURIComponent(filePath);
const url = new URL( const url = new URL(
@ -410,7 +412,7 @@ async function createOrUpdateFile(
)}/repository/files/${encodedPath}` )}/repository/files/${encodedPath}`
); );
const body = { const body: Record<string, any> = {
branch, branch,
content, content,
commit_message: commitMessage, commit_message: commitMessage,
@ -421,13 +423,37 @@ async function createOrUpdateFile(
// Check if file exists // Check if file exists
let method = "POST"; let method = "POST";
try { try {
await getFileContents(projectId, filePath, branch); // Get file contents to check existence and retrieve commit IDs
const fileData = await getFileContents(projectId, filePath, branch);
method = "PUT"; method = "PUT";
// If fileData is not an array, it's a file content object with commit IDs
if (!Array.isArray(fileData)) {
// Use commit IDs from the file data if not provided in parameters
if (!commit_id && fileData.commit_id) {
body.commit_id = fileData.commit_id;
} else if (commit_id) {
body.commit_id = commit_id;
}
if (!last_commit_id && fileData.last_commit_id) {
body.last_commit_id = fileData.last_commit_id;
} else if (last_commit_id) {
body.last_commit_id = last_commit_id;
}
}
} catch (error) { } catch (error) {
if (!(error instanceof Error && error.message.includes("File not found"))) { if (!(error instanceof Error && error.message.includes("File not found"))) {
throw error; throw error;
} }
// File doesn't exist, use POST // File doesn't exist, use POST - no need for commit IDs for new files
// But still use any provided as parameters if they exist
if (commit_id) {
body.commit_id = commit_id;
}
if (last_commit_id) {
body.last_commit_id = last_commit_id;
}
} }
const response = await fetch(url.toString(), { const response = await fetch(url.toString(), {
@ -934,7 +960,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
args.content, args.content,
args.commit_message, args.commit_message,
args.branch, args.branch,
args.previous_path args.previous_path,
args.last_commit_id,
args.commit_id
); );
return { return {
content: [{ type: "text", text: JSON.stringify(result, null, 2) }], content: [{ type: "text", text: JSON.stringify(result, null, 2) }],

View File

@ -43,7 +43,9 @@ export const GitLabFileContentSchema = z.object({
content_sha256: z.string(), // Changed from sha to match GitLab API content_sha256: z.string(), // Changed from sha to match GitLab API
ref: z.string(), // Added as GitLab requires branch reference ref: z.string(), // Added as GitLab requires branch reference
blob_id: z.string(), // Added to match GitLab API blob_id: z.string(), // Added to match GitLab API
commit_id: z.string(), // ID of the current file version
last_commit_id: z.string(), // Added to match GitLab API last_commit_id: z.string(), // Added to match GitLab API
execute_filemode: z.boolean().optional(), // Added to match GitLab API
}); });
export const GitLabDirectoryContentSchema = z.object({ export const GitLabDirectoryContentSchema = z.object({
@ -138,7 +140,7 @@ export const CreateBranchOptionsSchema = z.object({
export const GitLabCreateUpdateFileResponseSchema = z.object({ export const GitLabCreateUpdateFileResponseSchema = z.object({
file_path: z.string(), file_path: z.string(),
branch: z.string(), branch: z.string(),
commit_id: z.string(), // Changed from sha to match GitLab API commit_id: z.string().optional(), // Optional since it's not always returned by the API
content: GitLabFileContentSchema.optional(), content: GitLabFileContentSchema.optional(),
}); });
@ -263,6 +265,14 @@ export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
.string() .string()
.optional() .optional()
.describe("Path of the file to move/rename"), .describe("Path of the file to move/rename"),
last_commit_id: z
.string()
.optional()
.describe("Last known file commit ID"),
commit_id: z
.string()
.optional()
.describe("Current file commit ID (for update operations)"),
}); });
export const SearchRepositoriesSchema = z.object({ export const SearchRepositoriesSchema = z.object({