mu_sa
mu_sa

Reputation: 2735

Failed to lock refs/heads/master

I am relatively new to git and am facing this problem. The git push command shows the error below. I will explain to you from the beginning what I had been trying to do. I created a submodule, committed, and pushed it. The push throws the error below.

Salman@PC_HOME ~/git/breakit-web-app (master)
$ git push origin master
error: refs/heads/master does not point to a valid object!
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 421 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: bb/acl: salmanmanekia is allowed. accepted payload.
error: Ref refs/heads/master is at 6a47a0fd398610a75bdab8976f842dc0efd89f86 but expected 00000000000000000000000000000000000000000
remote: error: failed to lock refs/heads/master

To ssh://[email protected]/majuri/breakit-web-app.git
 ! [remote rejected] master -> master (failed to lock)
error: failed to push some refs to 'ssh://[email protected]/majuri/breakit-web-app.git'

Here is a screenshot: enter image description here

After that, I tried some solutions, but none of them worked. I will also explain briefly what I have been trying.

1: From the bitbucket repo, I noticed there are some dangling commits (the red arrow in picture 2), so I gave the following commands to solve that git gc and git prune.

2: I also tried commands like git revert HEAD and git push origin HEAD --force, but none seem to work. enter image description here

Other details:

$ git rev-parse --symbolic-full-name master
refs/heads/master

$ git rev-parse master
0da090c5cbde10ff19602a2722ae05231c30dff5

$ git show-ref master
0da090c5cbde10ff19602a2722ae05231c30dff5 refs/heads/master
6a47a0fd398610a75bdab8976f842dc0efd89f86 refs/remotes/origin/master

Thank you

Upvotes: 30

Views: 53253

Answers (5)

JESUS rose to life
JESUS rose to life

Reputation: 29

Based on this answer I wrote a NodeJS JavaScript program to run the following:

git checkout master
git fetch
git rebase origin/master
git push origin master:master

:

return await git_fix();
async function git_fix() {
    let commands = [
      "checkout master",
      "fetch",
      "rebase origin/master",
      "push origin master:master",
    ];
    return await command_line_git_multiple(commands);
  }
  async function command_line_git_multiple(commands) {
    let result = await list_map_async(
      commands,
      async (command) => await command_line_git(command),
    );
    return result;
  }
  async function command_line_git(args) {
    let command = string_combine_multiple(["git ", args]);
    return await command_line_exec(command);
  }
  function string_combine_multiple(list) {
    assert_arguments_length(arguments, 1);
    assert(list_is, [list]);
    let result = "";
    for (let l of list) {
      result = string_combine(result, l);
    }
    return result;
  }
  function assert(fn, args) {
    returns(fn, true, args);
  }
  function returns(fn, expected, args) {
    returns_message(fn, expected, args, message_get);
    function message_get() {
      return json_to(args);
    }
  }
  function returns_message(fn, expected, args, message_get) {
    let actual = fn(...args);
    let e = equal(actual, expected);
    assert_boolean_message(e, message_get);
  }
  function assert_boolean_message(condition, message_get) {
    if (condition === false) {
      error(message_get());
    }
  }
  function error(message) {
    throw new Error(message);
  }
  function equal(a, b) {
    return a === b;
  }
  function json_to(object) {
    return JSON.stringify(object);
  }
  function assert_arguments_length(args, expected) {
    assert(equal, [arguments.length, 2]);
    let actual = args.length;
    assert_message(equal, [actual, expected], () => ({
      message: "expecting different argument count",
      expected,
      actual,
    }));
  }
  function assert_message(fn, args, message_get) {
    return assert_message_string(fn, args, () => {
      let j = json_to(message_get());
      let limit = 1000;
      if (string_length(j > limit)) {
        return string_take(j, limit);
      }
      return j;
    });
  }
  function assert_message_string(fn, args, message_get) {
    returns_message(fn, true, args, message_get);
  }
  function string_length(input) {
    return input.length;
  }
  function string_take(input, count) {
    let length = string_length(input);
    assert_message(less_than_equal, [count, length], () => ({
      input,
      count,
      length,
    }));
    return string_substring(input, 0, count);
  }
  function less_than_equal(a, b) {
    return a <= b;
  }
  function string_substring(input, start, end) {
    assert_arguments_length(arguments, 3);
    return input.substring(start, end);
  }
  function list_is(candidate) {
    return Array.isArray(candidate);
  }
  function string_combine(a, b) {
    assert_arguments_length(arguments, 2);
    return a + b;
  }
  async function command_line_exec(command) {
    return await command_line_exec_generic(command, {});
  }
  async function command_line_exec_generic(command, options) {
    let c = await import_node("child_process");
    let { exec } = c;
    return await new Promise((resolve) => {
      exec(command, options, (error, stdout, stderr) => {
        resolve({
          error,
          stdout,
          stderr,
        });
      });
    });
  }
  async function import_node(libary_to_import) {
    let a;
    if (web_not_is()) {
      a = await import(libary_to_import);
    }
    return a;
  }
  function web_not_is() {
    return typeof window === "undefined";
  }
  async function list_map_async(list, mapper) {
    return await list_adder_async(async (la) => {
      await each_async(list, async (l) => {
        let mapped = mapper(l);
        let waited = await mapped;
        la(waited);
      });
    });
  }
  async function list_adder_async(lambda) {
    let result = [];
    await lambda((item) => list_add(result, item));
    return result;
  }
  function list_add(list, item) {
    assert_arguments_length(arguments, 2);
    list.push(item);
  }
  async function each_async(list, lambda) {
    for (let element of list) {
      await lambda(element);
    }
  }

This way I can run a single function to fix this problem should it ever happen again in the future

Disclaimer: This code was plucked out of my repository using a command and is not the minimal code needed to solve this specific problem

Sample output:

[
  {
    error: null,
    stdout: "Your branch is up to date with 'origin/master'.\n",
    stderr: "Already on 'master'\n"
  },
  { error: null, stdout: '', stderr: '' },
  {
    error: null,
    stdout: 'Current branch master is up to date.\n',
    stderr: ''
  },
  { error: null, stdout: '', stderr: 'Everything up-to-date\n' }
]

Upvotes: -1

StarShine
StarShine

Reputation: 2060

There is at least one other scenario where you are amending a pending commit that was not yet pushed, while also rebasing the working copy on master using 'git pull'. In that case the rebase will not continue and give the error mentioned by the OP. A simple 'rebase --continue' will not work.

interactive rebase in progress; onto 04352133b9
Last commands done (5 commands done):
   pick 6fddf156e5 [XYZ123] Modification1
   pick 847c52b89e [ABC456] Modification2
  (see more in file .git/rebase-merge/done)
No commands remaining.
You are currently editing a commit while rebasing branch 'master' on '04352133b9'.
  (use "git commit --amend" to amend the current commit)
  (use "git rebase --continue" once you are satisfied with your changes)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)

The underlying reason this happened is because I'm using command line git tools while also keeping a visual representation of the git branches open in a commercial tool called SmartGit. It usually works well, but synchronizing with the locked .git files gives problems and this is one of those.

I resolved it by first ending the amend using

git commit --amend

which will effectively do nothing, just signal that the amend is finished.

Then you can abort the rebase

git fetch --all
git rebase --abort

and re-request the pull to rebase the working version on master.

git pull

Then you can re-amend the work you were going to push.

git commit --amend

I'm not a git export and it the order sequence or commands might need modifications in your case. In my case it seems to have worked out.

Upvotes: 1

Flows
Flows

Reputation: 3863

You have to update the HEAD known by git. It will be transparent for you.

  1. Go to master branch

    git checkout master
    
  2. Get updates from the remote to your local repository

    git fetch
    
  3. Update your local repository using rebase instead of merge. See there difference between git pull and git rebase

    git rebase origin/master
    
  4. Push your master branch

    git push origin master:master
    

Upvotes: 35

Adithya
Adithya

Reputation: 59

git pull origin master --rebase

this worked for me

Upvotes: 2

Ali Turki
Ali Turki

Reputation: 1475

If you tried all these above steps and did not work, try the following command.

rm -fr ".git/rebase-merge"

Upvotes: 4

Related Questions