int beargit_checkout(const char* arg, int new_branch) { // Get the current branch char current_branch[BRANCHNAME_SIZE]; read_string_from_file(".beargit/.current_branch", current_branch, BRANCHNAME_SIZE); // If not detached, leave the current branch by storing the current HEAD into that branch's file... if (strlen(current_branch)) { char current_branch_file[BRANCHNAME_SIZE+50]; sprintf(current_branch_file, ".beargit/.branch_%s", current_branch); fs_cp(".beargit/.prev", current_branch_file); } // Check whether the argument is a commit ID. If yes, we just change to detached mode // without actually having to change into any other branch. if (is_it_a_commit_id(arg)) { char commit_dir[FILENAME_SIZE] = ".beargit/"; strcat(commit_dir, arg); // ...and setting the current branch to none (i.e., detached). write_string_to_file(".beargit/.current_branch", ""); return checkout_commit(arg); } // Read branches file (giving us the HEAD commit id for that branch). int branch_exists = (get_branch_number(arg) >= 0); // Check for errors. if (!(!branch_exists || !new_branch)) { fprintf(stderr, "ERROR: A branch named %s already exists.\n", arg); return 1; } else if (!branch_exists && !new_branch) { fprintf(stderr, "ERROR: No branch or commit %s exists.\n", arg); return 1; } // Just a better name, since we now know the argument is a branch name. const char* branch_name = arg; // File for the branch we are changing into. char branch_file[BRANCHNAME_SIZE + 50] = ".beargit/.branch_"; strcat(branch_file, branch_name); // Update the branch file if new branch is created (now it can't go wrong anymore) if (new_branch) { FILE* fbranches = fopen(".beargit/.branches", "a"); fprintf(fbranches, "%s\n", branch_name); fclose(fbranches); fs_cp(".beargit/.prev", branch_file); } write_string_to_file(".beargit/.current_branch", branch_name); // Read the head commit ID of this branch. char branch_head_commit_id[COMMIT_ID_SIZE]; read_string_from_file(branch_file, branch_head_commit_id, COMMIT_ID_SIZE); // Check out the actual commit. return checkout_commit(branch_head_commit_id); }
int beargit_checkout(const char* arg, int new_branch) { // Get the current branch char current_branch[BRANCHNAME_SIZE]; read_string_from_file(".beargit/.current_branch", current_branch, BRANCHNAME_SIZE); //MISTAKE 1: the second arguments should be current_branch rather than "current_branch" // If not detached, update the current branch by storing the current HEAD into that branch's file... // Even if we cancel later, this is still ok. if (strlen(current_branch)) { char current_branch_file[BRANCHNAME_SIZE+50]; sprintf(current_branch_file, ".beargit/.branch_%s", current_branch); fs_cp(".beargit/.prev", current_branch_file); } // Check whether the argument is a commit ID. If yes, we just stay in detached mode // without actually having to change into any other branch. if (is_it_a_commit_id(arg)) { char commit_dir[FILENAME_SIZE] = ".beargit/"; strcat(commit_dir, arg); if (!fs_check_dir_exists(commit_dir)) { fprintf(stderr, "ERROR: Commit %s does not exist\n", arg); return 1; } // Set the current branch to none (i.e., detached). write_string_to_file(".beargit/.current_branch", ""); return checkout_commit(arg); } // Just a better name, since we now know the argument is a branch name. const char* branch_name = arg; // Read branches file (giving us the HEAD commit id for that branch). // branch_exists=1: exits // branch_exists=0: not exist int branch_exists = (get_branch_number(branch_name) >= 0); // Check for errors. if (!(!branch_exists || !new_branch)) { fprintf(stderr, "ERROR: A branch named %s already exists\n", branch_name); return 1; //MISTAKE 2: no branch exist error should only been print if new_branch evaluate to false and branch_exist ealuate to false. } else if (!branch_exists && !new_branch) { fprintf(stderr, "ERROR: No branch %s exists\n", branch_name); return 1; } // File for the branch we are changing into. //MISTAKES 3: if use char* branch_file, it is only for reading, can apply strcat //should change to char branch_file [] = " " char branch_file[] = ".beargit/.branch_"; strcat(branch_file, branch_name); // Update the branch file if new branch is created (now it can't go wrong anymore) if (new_branch) { FILE* fbranches = fopen(".beargit/.branches", "a"); fprintf(fbranches, "%s\n", branch_name); fclose(fbranches); fs_cp(".beargit/.prev", branch_file); } write_string_to_file(".beargit/.current_branch", branch_name); // Read the head commit ID of this branch. char branch_head_commit_id[COMMIT_ID_SIZE]; read_string_from_file(branch_file, branch_head_commit_id, COMMIT_ID_SIZE); // Check out the actual commit. return checkout_commit(branch_head_commit_id); }