Why can't I merge my git dev branch to master even though master only contains an empty README?Undoing a git rebaseGit refusing to merge unrelated histories. What is 'unrelated histories'?How can I know if a branch has been already merged into master?Git for beginners: The definitive practical guideHow to selectively merge or pick changes from another branch in Git?Git workflow and rebase vs merge questionsGit merge reports “Already up-to-date” though there is a differenceMake the current Git branch a master branchHow to replace master branch in Git, entirely, from another branch?What is the best (and safest) way to merge a Git branch into master?How can I delete all Git branches which have been merged?Git merge master into feature branch

Why did Old English lose both thorn and eth?

Delete elements less than the last largest element

What does the multimeter dial do internally?

Why do people prefer metropolitan areas, considering monsters and villains?

How to "add vert" in blender 2.8?

Is there a formal/better word than "skyrocket" for the given context?

Did depressed people far more accurately estimate how many monsters they killed in a video game?

Gory anime with pink haired girl escaping an asylum

Can a landlord force all residents to use the landlord's in-house debit card accounts?

Find out what encryptor name my database is using

What do you call a situation where you have choices but no good choice?

Can the word "desk" be used as a verb?

What term do you use for someone who acts impulsively?

When do flights get cancelled due to fog?

Is this really the Saturn V computer only, or are there other systems here as well?

Clarinets in the Rite of Spring

Draw a diagram with rectangles

I'm feeling like my character doesn't fit the campaign

Moving millions of files to a different directory with specfic name patterns

Users forgotting to regenerate PDF before sending it

How do I talk to my wife about unrealistic expectations?

Intern not wearing safety equipment; how could I have handled this differently?

How do I separate enchants from items?

What is the meaning of "prairie-dog" in this sentence?



Why can't I merge my git dev branch to master even though master only contains an empty README?


Undoing a git rebaseGit refusing to merge unrelated histories. What is 'unrelated histories'?How can I know if a branch has been already merged into master?Git for beginners: The definitive practical guideHow to selectively merge or pick changes from another branch in Git?Git workflow and rebase vs merge questionsGit merge reports “Already up-to-date” though there is a differenceMake the current Git branch a master branchHow to replace master branch in Git, entirely, from another branch?What is the best (and safest) way to merge a Git branch into master?How can I delete all Git branches which have been merged?Git merge master into feature branch






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1















I'm at the end of building my app that has been developed on my dev branch and would like to now add it to master for production.



However, when I checkout to master and run git merge dev I receive a fatal error of refusing to merge unrelated histories. Unfortunately, git pull origin master --allow-unrelated-histories didn't help resolve the error.



This is the status of master:




  • git status shows that my "branch is up to date with 'origin/master'".

  • The only file in the repo is an empty README.md.

  • GitLab has labelled this a "stale" branch.

  • It is a protected branch.

Help me understand why am I not able to merge.



EDIT: I should also mention that git log produces the following:



commit ac22443836aeaf8abe38aa3761970a4cd3835587 (HEAD -> master, origin/master)
Author: // my info
Date: Fri Dec 21 03:25:26 2018 -0700

Initial commit
(END)









share|improve this question
























  • Does master and dev have a common ancestor (I mean a common commit parent) ?

    – Jona
    Mar 25 at 22:50











  • I went through and it actually didn't seem to share a common ancestor and that may be the crux of the issue. But it looks like a solution that was posted (but then deleted by another user...not sure why) did the trick. Basically, git merge dev --allow-unrelated-histories.

    – Mix Master Mike
    Mar 25 at 23:16











  • How did you set up your local dev environment? Did you clone the repo you want to merge with, and then git checkout -b dev to create your dev branch?

    – Joe McMahon
    Mar 25 at 23:20











  • @JoeMcMahon that's what I thought I did as that's my modus operandi. But for whatever reason as I went back through my logs, I didn't see dev branch off of master or share the same commit ID as master. So this makes me wonder. Even though this was done 3 months ago, it seems like ages. And with the fix I described above master is ahead of 'origin/master' by 720 commits.

    – Mix Master Mike
    Mar 25 at 23:26

















1















I'm at the end of building my app that has been developed on my dev branch and would like to now add it to master for production.



However, when I checkout to master and run git merge dev I receive a fatal error of refusing to merge unrelated histories. Unfortunately, git pull origin master --allow-unrelated-histories didn't help resolve the error.



This is the status of master:




  • git status shows that my "branch is up to date with 'origin/master'".

  • The only file in the repo is an empty README.md.

  • GitLab has labelled this a "stale" branch.

  • It is a protected branch.

Help me understand why am I not able to merge.



EDIT: I should also mention that git log produces the following:



commit ac22443836aeaf8abe38aa3761970a4cd3835587 (HEAD -> master, origin/master)
Author: // my info
Date: Fri Dec 21 03:25:26 2018 -0700

Initial commit
(END)









share|improve this question
























  • Does master and dev have a common ancestor (I mean a common commit parent) ?

    – Jona
    Mar 25 at 22:50











  • I went through and it actually didn't seem to share a common ancestor and that may be the crux of the issue. But it looks like a solution that was posted (but then deleted by another user...not sure why) did the trick. Basically, git merge dev --allow-unrelated-histories.

    – Mix Master Mike
    Mar 25 at 23:16











  • How did you set up your local dev environment? Did you clone the repo you want to merge with, and then git checkout -b dev to create your dev branch?

    – Joe McMahon
    Mar 25 at 23:20











  • @JoeMcMahon that's what I thought I did as that's my modus operandi. But for whatever reason as I went back through my logs, I didn't see dev branch off of master or share the same commit ID as master. So this makes me wonder. Even though this was done 3 months ago, it seems like ages. And with the fix I described above master is ahead of 'origin/master' by 720 commits.

    – Mix Master Mike
    Mar 25 at 23:26













1












1








1








I'm at the end of building my app that has been developed on my dev branch and would like to now add it to master for production.



However, when I checkout to master and run git merge dev I receive a fatal error of refusing to merge unrelated histories. Unfortunately, git pull origin master --allow-unrelated-histories didn't help resolve the error.



This is the status of master:




  • git status shows that my "branch is up to date with 'origin/master'".

  • The only file in the repo is an empty README.md.

  • GitLab has labelled this a "stale" branch.

  • It is a protected branch.

Help me understand why am I not able to merge.



EDIT: I should also mention that git log produces the following:



commit ac22443836aeaf8abe38aa3761970a4cd3835587 (HEAD -> master, origin/master)
Author: // my info
Date: Fri Dec 21 03:25:26 2018 -0700

Initial commit
(END)









share|improve this question
















I'm at the end of building my app that has been developed on my dev branch and would like to now add it to master for production.



However, when I checkout to master and run git merge dev I receive a fatal error of refusing to merge unrelated histories. Unfortunately, git pull origin master --allow-unrelated-histories didn't help resolve the error.



This is the status of master:




  • git status shows that my "branch is up to date with 'origin/master'".

  • The only file in the repo is an empty README.md.

  • GitLab has labelled this a "stale" branch.

  • It is a protected branch.

Help me understand why am I not able to merge.



EDIT: I should also mention that git log produces the following:



commit ac22443836aeaf8abe38aa3761970a4cd3835587 (HEAD -> master, origin/master)
Author: // my info
Date: Fri Dec 21 03:25:26 2018 -0700

Initial commit
(END)






git gitlab






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 25 at 23:14









Joe McMahon

2,57315 silver badges28 bronze badges




2,57315 silver badges28 bronze badges










asked Mar 25 at 22:33









Mix Master MikeMix Master Mike

1622 silver badges15 bronze badges




1622 silver badges15 bronze badges












  • Does master and dev have a common ancestor (I mean a common commit parent) ?

    – Jona
    Mar 25 at 22:50











  • I went through and it actually didn't seem to share a common ancestor and that may be the crux of the issue. But it looks like a solution that was posted (but then deleted by another user...not sure why) did the trick. Basically, git merge dev --allow-unrelated-histories.

    – Mix Master Mike
    Mar 25 at 23:16











  • How did you set up your local dev environment? Did you clone the repo you want to merge with, and then git checkout -b dev to create your dev branch?

    – Joe McMahon
    Mar 25 at 23:20











  • @JoeMcMahon that's what I thought I did as that's my modus operandi. But for whatever reason as I went back through my logs, I didn't see dev branch off of master or share the same commit ID as master. So this makes me wonder. Even though this was done 3 months ago, it seems like ages. And with the fix I described above master is ahead of 'origin/master' by 720 commits.

    – Mix Master Mike
    Mar 25 at 23:26

















  • Does master and dev have a common ancestor (I mean a common commit parent) ?

    – Jona
    Mar 25 at 22:50











  • I went through and it actually didn't seem to share a common ancestor and that may be the crux of the issue. But it looks like a solution that was posted (but then deleted by another user...not sure why) did the trick. Basically, git merge dev --allow-unrelated-histories.

    – Mix Master Mike
    Mar 25 at 23:16











  • How did you set up your local dev environment? Did you clone the repo you want to merge with, and then git checkout -b dev to create your dev branch?

    – Joe McMahon
    Mar 25 at 23:20











  • @JoeMcMahon that's what I thought I did as that's my modus operandi. But for whatever reason as I went back through my logs, I didn't see dev branch off of master or share the same commit ID as master. So this makes me wonder. Even though this was done 3 months ago, it seems like ages. And with the fix I described above master is ahead of 'origin/master' by 720 commits.

    – Mix Master Mike
    Mar 25 at 23:26
















Does master and dev have a common ancestor (I mean a common commit parent) ?

– Jona
Mar 25 at 22:50





Does master and dev have a common ancestor (I mean a common commit parent) ?

– Jona
Mar 25 at 22:50













I went through and it actually didn't seem to share a common ancestor and that may be the crux of the issue. But it looks like a solution that was posted (but then deleted by another user...not sure why) did the trick. Basically, git merge dev --allow-unrelated-histories.

– Mix Master Mike
Mar 25 at 23:16





I went through and it actually didn't seem to share a common ancestor and that may be the crux of the issue. But it looks like a solution that was posted (but then deleted by another user...not sure why) did the trick. Basically, git merge dev --allow-unrelated-histories.

– Mix Master Mike
Mar 25 at 23:16













How did you set up your local dev environment? Did you clone the repo you want to merge with, and then git checkout -b dev to create your dev branch?

– Joe McMahon
Mar 25 at 23:20





How did you set up your local dev environment? Did you clone the repo you want to merge with, and then git checkout -b dev to create your dev branch?

– Joe McMahon
Mar 25 at 23:20













@JoeMcMahon that's what I thought I did as that's my modus operandi. But for whatever reason as I went back through my logs, I didn't see dev branch off of master or share the same commit ID as master. So this makes me wonder. Even though this was done 3 months ago, it seems like ages. And with the fix I described above master is ahead of 'origin/master' by 720 commits.

– Mix Master Mike
Mar 25 at 23:26





@JoeMcMahon that's what I thought I did as that's my modus operandi. But for whatever reason as I went back through my logs, I didn't see dev branch off of master or share the same commit ID as master. So this makes me wonder. Even though this was done 3 months ago, it seems like ages. And with the fix I described above master is ahead of 'origin/master' by 720 commits.

– Mix Master Mike
Mar 25 at 23:26












4 Answers
4






active

oldest

votes


















0














If --allow-unrelated-hhistories was necessary, that means you actually had the equivalent of two different repositories that you merged together.



I suspect this happened because you didn't clone the original repo first before creating your dev branch and doing work. My deduction from your description is that you did a git init, checked out a dev branch, and then added the remote repo as origin when you wanted to merge (this worked because your local repo had no remotes).



Attempting to merge at that point would get the 'unrelated histories' because the two repos are, in fact not related; the original was created and pushed to GitLab, and a completely separate one was created when you did your git init to create the local. Cloning the original would create a local repository that was related, because it shared that initial README commit.



This is, indeed, the only way to fix this issue, and as soon as you push to GitLab, the local and the remote will be in sync -- but you should always clone to avoid the problem in the first place.






share|improve this answer























  • Were you the one that suggested running git merge dev --allow-unrelated-histories? Someone did then deleted this solution. But it worked. I want to give credit where credit is due.

    – Mix Master Mike
    Mar 25 at 23:29












  • Wasn't me, sorry -- but that was the right answer for this situation. I've used it when creating a mono-repo out of multiple repos, so it's not inherently a bad thing. It's just that, as you say, clone-branch-commit-merge/rebase is better.

    – Joe McMahon
    Mar 25 at 23:31











  • much thanks for shedding light on my blunder.

    – Mix Master Mike
    Mar 25 at 23:36


















0














If, like it was said, master and dev doesn't have a common (parent) commit, I would try to create new branch from master and cherry-pick all commits from dev into it:
git cherry-pick startHash^..endHash
For example git cherry-pick 1234^..5678.
Then you should be able to merge this new branch into master






share|improve this answer






























    0














    You probably checked "[ ] Create repository with a README" when you created the repository.



    When master is really empty, I see the following options



    • go to gitlab, change the default branch to something else and remove the master branch in the web interface (there, it is possible to delete protected branches). Or,


    • unprotect master


    Now you can force-push your dev Branch to gitlab (e.g. git push -f dev:master).



    NOTE: this option is a no-go for branches resp. repositories which are used by other peoples. In this case do:



    git fetch gitlab master
    git merge -s ours FETCH_HEAD


    and push this branch.






    share|improve this answer























    • For clarification is git fetch gitlab master and git merge -s ours FETCH_HEAD is executed from my master branch, correct?

      – Mix Master Mike
      Mar 25 at 23:50











    • git fetch can be executed everywhere (even in bare repositories). For git merge you have to checkout the branch which shall become master.

      – ensc
      Mar 25 at 23:54


















    0














    You already fixed (?) this using --allow-unrelated-histories and there's no real reason not to just leave that. But in case you are still wondering...



    What happened, and how you (probably) got here



    The first key to using Git is to understand that Git is all about commits. Of course, this also requires that you understand, in a reasonably deep sort of way, what a commit is. What it is, is pretty short and simple: it's a permanent (mostly) and immutable (entirely) snapshot plus some metadata. The snapshot contains all of your files—well, all of them as of the time you made the commit—and the metadata has:



    • your name and email address, and the time you made the commit;

    • your log message, i.e., why you made this commit; and, crucially,

    • the hash ID of the commit that comes just before this commit, defined as the parent of this commit.

    Every commit is unique—for many reasons, including the time-stamp mentioned above—and every unique commit gets a unique hash ID. That hash ID, some big ugly string of hexadecimal characters, seems random, but is actually a cryptographic checksum of the contents of the commit. It's also the True Name, as it were, of that commit: that ID means that commit, and only that commit. No other commit will ever have that hash ID. That hash ID will always mean that commit.



    Git actually finds the commit by hash ID. So the hash ID is crucial. Of course, it's also impossible for humans to remember. So Git gives us a way to remember the latest hash ID, and that way is a branch name like master or dev.



    The name only has to remember the last commit because each commit remembers its parent's hash on its own. That is, given a tiny repository with just three commits, where we replace the actual hash IDs with a single uppercase letter, we can draw this:



    A <-B <-C <-- master


    The name master remembers the hash ID of C. C itself—the actual commit, retrieved by hash ID—remembers the hash ID of B, and B itself remembers the hash ID of A.



    When something remembers the hash ID of some other commit, we say that this something points to the commit. So the name master points to C, C points to B, and B points to A. Those three commits—C, then B, then Aare the history in the repository.



    Note that A doesn't point anywhere. It literally can't, because it was the first commit. There was no earlier commit. So it just doesn't, and Git calls this a root commit. All non-empty repositories have to have at least one root commit. Most, probably, have exactly one ... but yours has two.



    Normal branching and merging



    Let's take a quick look at the more normal way to make branches. Suppose we have just these three commits, pointed-to by master. We ask Git to make a new branch name, pointing to the same commit as master:



    A--B--C <-- dev (HEAD), master


    Both names identify commit C, so commit C is on—and is the tip commit of—both branches, and all three commits are on both branches. But now we make a new commit. The process of making a new commit—with the usual edit and git add and git commit—makes a new snapshot, adds our name and email and timestamp and so on, uses the current commit C as the saved hash, and builds the new commit. The new commit gets some big ugly hash ID, but we'll just call it D:



    A--B--C <-- dev (HEAD), master

    D


    Since D's parent is C, D points back to C. But now the magic happens: Git writes D's hash ID into the current branch name—the one HEAD is attached to—so now we have:



    A--B--C <-- master

    D <-- dev (HEAD)


    and voila, we have a new branch. (Well, we had it before, pointing to C. Most people don't like to think about it that way though, they want to call D the branch. In fact, the branch is D-C-B-A!)



    Over time we add some commits to both branches:



    A--B--C-----J----K----L <-- master

    D--E--F--G--H--I <-- dev


    We git checkout master and git merge dev. Git will find the merge base commit for us, where dev and master diverged. That's obviously commit C since that's where the two branches rejoin in the past. Git will compare C vs L to see what we changed on master, compare C vs I to see what we changed on dev, and combine the changes. Git applies the combined changes to the snapshot in C—to the merge base—and makes a new merge commit M, which goes on our current HEAD branch as usual, updating that branch name so that master points to M:



    A--B--C-----J----K----L--M <-- master (HEAD)
    /
    D--E--F--G--H--I <-- dev


    What's special about M is that it has two backwards links: it goes back to L, as all commits would, but it has a second parent I, which is the current tip commit of branch dev. Other than the two parents, though, it's quite ordinary: it has a snapshot as usual, and our name and email and timestamp and a log message.



    Abnormal branching



    There's nothing in Git that stops you from making extra root commits. It's just a little bit tricky. Suppose that, somehow, you did this:



    A <-- master

    B--C--D--...--L <-- dev (HEAD)


    Once you have this situation, git checkout master; git merge dev just gives you an error. That's because the usual method of finding a merge base—starting at the two branch tips and working backwards—never finds a common commit.



    Adding --allow-unrelated-histories tells Git to pretend that there's a special empty commit before both branches:



     A <-- master (HEAD)
    0
    B--C--D--...--L <-- dev


    Now Git can diff 0 vs A to see what you changed on master, and 0 vs L to see what they changed on dev. On master, you added every file. On dev, you also added every file. As long as those are different files, the way to combine those two changes is to add the master files from commit A to the dev files from commit L, apply those changes to the empty null commit, and commit the result, with parents going back to both A and L:



    A---------------M <-- master (HEAD)
    /
    B--C--D--...--L <-- dev


    How you (probably) got here



    There's a git checkout option, git checkout --orphan, that sets this state up. But that's probably not what you did. The state this sets up is the same state you're in when you create a new, empty repository with git init:



    [no commits] <-- [no branches]


    There are no branches, and yet Git will say that you're on branch master. You can't be on master: it doesn't exist. But you are, even though it doesn't exist. The way Git manages this is that it puts the name master into HEAD (.git/HEAD, actually) without first creating a branch named master. It can't create the branch because a branch name has to contain a valid hash ID, and there aren't any.



    So, when you run git commit, Git detects this anomalous state: that HEAD says master but master doesn't exist. That's what triggers Git to make our root commit A. Then Git writes A's hash ID into the branch, which creates the branch, and now we have:



    A <-- master (HEAD)


    which is just what we wanted.



    But suppose, while we're in this weird no-commits-yet state, we run:



    git checkout -b dev


    This tells Git: Put the name dev into HEAD. It does that without complaint, even though there's no master either. Then we make our first commit, but for no obvious reason, we'll pick B as its one-letter stand-in for its hash ID:



    B <-- dev (HEAD)


    Meanwhile, having run git init here, then git checkout -b dev, then done something and git commit, we'll go over to $WebHostingProvider—whether that's GitHub or GitLab or Bitbucket or whatever—and use its make me a new repository clicky buttons. Those usually have an option: create an initial commit with README and/or LICENSE files and such. If that option is checked—or the don't option is unchecked—they go ahead and make a first commit and a master:



    A <-- master (HEAD)


    Now you connect your repository to theirs and have your Git download any commits they have that you don't:



    A <-- origin/master

    B <-- dev (HEAD)


    You can now proceed to add lots of commits, never noticing that your dev branch is not related to their master branch (which your Git is calling origin/master).



    Later, you run:



    git checkout master


    Your Git notices that you don't have a master, but that you do have an origin/master. So your Git creates a master for you, pointing to the same commit as origin/master, and attaches your HEAD to your new master:



    A <-- master (HEAD), origin/master

    B--C--D--...--L <-- dev


    and voila, you're in the pickle you were in.






    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55347352%2fwhy-cant-i-merge-my-git-dev-branch-to-master-even-though-master-only-contains-a%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      If --allow-unrelated-hhistories was necessary, that means you actually had the equivalent of two different repositories that you merged together.



      I suspect this happened because you didn't clone the original repo first before creating your dev branch and doing work. My deduction from your description is that you did a git init, checked out a dev branch, and then added the remote repo as origin when you wanted to merge (this worked because your local repo had no remotes).



      Attempting to merge at that point would get the 'unrelated histories' because the two repos are, in fact not related; the original was created and pushed to GitLab, and a completely separate one was created when you did your git init to create the local. Cloning the original would create a local repository that was related, because it shared that initial README commit.



      This is, indeed, the only way to fix this issue, and as soon as you push to GitLab, the local and the remote will be in sync -- but you should always clone to avoid the problem in the first place.






      share|improve this answer























      • Were you the one that suggested running git merge dev --allow-unrelated-histories? Someone did then deleted this solution. But it worked. I want to give credit where credit is due.

        – Mix Master Mike
        Mar 25 at 23:29












      • Wasn't me, sorry -- but that was the right answer for this situation. I've used it when creating a mono-repo out of multiple repos, so it's not inherently a bad thing. It's just that, as you say, clone-branch-commit-merge/rebase is better.

        – Joe McMahon
        Mar 25 at 23:31











      • much thanks for shedding light on my blunder.

        – Mix Master Mike
        Mar 25 at 23:36















      0














      If --allow-unrelated-hhistories was necessary, that means you actually had the equivalent of two different repositories that you merged together.



      I suspect this happened because you didn't clone the original repo first before creating your dev branch and doing work. My deduction from your description is that you did a git init, checked out a dev branch, and then added the remote repo as origin when you wanted to merge (this worked because your local repo had no remotes).



      Attempting to merge at that point would get the 'unrelated histories' because the two repos are, in fact not related; the original was created and pushed to GitLab, and a completely separate one was created when you did your git init to create the local. Cloning the original would create a local repository that was related, because it shared that initial README commit.



      This is, indeed, the only way to fix this issue, and as soon as you push to GitLab, the local and the remote will be in sync -- but you should always clone to avoid the problem in the first place.






      share|improve this answer























      • Were you the one that suggested running git merge dev --allow-unrelated-histories? Someone did then deleted this solution. But it worked. I want to give credit where credit is due.

        – Mix Master Mike
        Mar 25 at 23:29












      • Wasn't me, sorry -- but that was the right answer for this situation. I've used it when creating a mono-repo out of multiple repos, so it's not inherently a bad thing. It's just that, as you say, clone-branch-commit-merge/rebase is better.

        – Joe McMahon
        Mar 25 at 23:31











      • much thanks for shedding light on my blunder.

        – Mix Master Mike
        Mar 25 at 23:36













      0












      0








      0







      If --allow-unrelated-hhistories was necessary, that means you actually had the equivalent of two different repositories that you merged together.



      I suspect this happened because you didn't clone the original repo first before creating your dev branch and doing work. My deduction from your description is that you did a git init, checked out a dev branch, and then added the remote repo as origin when you wanted to merge (this worked because your local repo had no remotes).



      Attempting to merge at that point would get the 'unrelated histories' because the two repos are, in fact not related; the original was created and pushed to GitLab, and a completely separate one was created when you did your git init to create the local. Cloning the original would create a local repository that was related, because it shared that initial README commit.



      This is, indeed, the only way to fix this issue, and as soon as you push to GitLab, the local and the remote will be in sync -- but you should always clone to avoid the problem in the first place.






      share|improve this answer













      If --allow-unrelated-hhistories was necessary, that means you actually had the equivalent of two different repositories that you merged together.



      I suspect this happened because you didn't clone the original repo first before creating your dev branch and doing work. My deduction from your description is that you did a git init, checked out a dev branch, and then added the remote repo as origin when you wanted to merge (this worked because your local repo had no remotes).



      Attempting to merge at that point would get the 'unrelated histories' because the two repos are, in fact not related; the original was created and pushed to GitLab, and a completely separate one was created when you did your git init to create the local. Cloning the original would create a local repository that was related, because it shared that initial README commit.



      This is, indeed, the only way to fix this issue, and as soon as you push to GitLab, the local and the remote will be in sync -- but you should always clone to avoid the problem in the first place.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Mar 25 at 23:27









      Joe McMahonJoe McMahon

      2,57315 silver badges28 bronze badges




      2,57315 silver badges28 bronze badges












      • Were you the one that suggested running git merge dev --allow-unrelated-histories? Someone did then deleted this solution. But it worked. I want to give credit where credit is due.

        – Mix Master Mike
        Mar 25 at 23:29












      • Wasn't me, sorry -- but that was the right answer for this situation. I've used it when creating a mono-repo out of multiple repos, so it's not inherently a bad thing. It's just that, as you say, clone-branch-commit-merge/rebase is better.

        – Joe McMahon
        Mar 25 at 23:31











      • much thanks for shedding light on my blunder.

        – Mix Master Mike
        Mar 25 at 23:36

















      • Were you the one that suggested running git merge dev --allow-unrelated-histories? Someone did then deleted this solution. But it worked. I want to give credit where credit is due.

        – Mix Master Mike
        Mar 25 at 23:29












      • Wasn't me, sorry -- but that was the right answer for this situation. I've used it when creating a mono-repo out of multiple repos, so it's not inherently a bad thing. It's just that, as you say, clone-branch-commit-merge/rebase is better.

        – Joe McMahon
        Mar 25 at 23:31











      • much thanks for shedding light on my blunder.

        – Mix Master Mike
        Mar 25 at 23:36
















      Were you the one that suggested running git merge dev --allow-unrelated-histories? Someone did then deleted this solution. But it worked. I want to give credit where credit is due.

      – Mix Master Mike
      Mar 25 at 23:29






      Were you the one that suggested running git merge dev --allow-unrelated-histories? Someone did then deleted this solution. But it worked. I want to give credit where credit is due.

      – Mix Master Mike
      Mar 25 at 23:29














      Wasn't me, sorry -- but that was the right answer for this situation. I've used it when creating a mono-repo out of multiple repos, so it's not inherently a bad thing. It's just that, as you say, clone-branch-commit-merge/rebase is better.

      – Joe McMahon
      Mar 25 at 23:31





      Wasn't me, sorry -- but that was the right answer for this situation. I've used it when creating a mono-repo out of multiple repos, so it's not inherently a bad thing. It's just that, as you say, clone-branch-commit-merge/rebase is better.

      – Joe McMahon
      Mar 25 at 23:31













      much thanks for shedding light on my blunder.

      – Mix Master Mike
      Mar 25 at 23:36





      much thanks for shedding light on my blunder.

      – Mix Master Mike
      Mar 25 at 23:36













      0














      If, like it was said, master and dev doesn't have a common (parent) commit, I would try to create new branch from master and cherry-pick all commits from dev into it:
      git cherry-pick startHash^..endHash
      For example git cherry-pick 1234^..5678.
      Then you should be able to merge this new branch into master






      share|improve this answer



























        0














        If, like it was said, master and dev doesn't have a common (parent) commit, I would try to create new branch from master and cherry-pick all commits from dev into it:
        git cherry-pick startHash^..endHash
        For example git cherry-pick 1234^..5678.
        Then you should be able to merge this new branch into master






        share|improve this answer

























          0












          0








          0







          If, like it was said, master and dev doesn't have a common (parent) commit, I would try to create new branch from master and cherry-pick all commits from dev into it:
          git cherry-pick startHash^..endHash
          For example git cherry-pick 1234^..5678.
          Then you should be able to merge this new branch into master






          share|improve this answer













          If, like it was said, master and dev doesn't have a common (parent) commit, I would try to create new branch from master and cherry-pick all commits from dev into it:
          git cherry-pick startHash^..endHash
          For example git cherry-pick 1234^..5678.
          Then you should be able to merge this new branch into master







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 25 at 23:33









          zdolnyzdolny

          3216 silver badges13 bronze badges




          3216 silver badges13 bronze badges





















              0














              You probably checked "[ ] Create repository with a README" when you created the repository.



              When master is really empty, I see the following options



              • go to gitlab, change the default branch to something else and remove the master branch in the web interface (there, it is possible to delete protected branches). Or,


              • unprotect master


              Now you can force-push your dev Branch to gitlab (e.g. git push -f dev:master).



              NOTE: this option is a no-go for branches resp. repositories which are used by other peoples. In this case do:



              git fetch gitlab master
              git merge -s ours FETCH_HEAD


              and push this branch.






              share|improve this answer























              • For clarification is git fetch gitlab master and git merge -s ours FETCH_HEAD is executed from my master branch, correct?

                – Mix Master Mike
                Mar 25 at 23:50











              • git fetch can be executed everywhere (even in bare repositories). For git merge you have to checkout the branch which shall become master.

                – ensc
                Mar 25 at 23:54















              0














              You probably checked "[ ] Create repository with a README" when you created the repository.



              When master is really empty, I see the following options



              • go to gitlab, change the default branch to something else and remove the master branch in the web interface (there, it is possible to delete protected branches). Or,


              • unprotect master


              Now you can force-push your dev Branch to gitlab (e.g. git push -f dev:master).



              NOTE: this option is a no-go for branches resp. repositories which are used by other peoples. In this case do:



              git fetch gitlab master
              git merge -s ours FETCH_HEAD


              and push this branch.






              share|improve this answer























              • For clarification is git fetch gitlab master and git merge -s ours FETCH_HEAD is executed from my master branch, correct?

                – Mix Master Mike
                Mar 25 at 23:50











              • git fetch can be executed everywhere (even in bare repositories). For git merge you have to checkout the branch which shall become master.

                – ensc
                Mar 25 at 23:54













              0












              0








              0







              You probably checked "[ ] Create repository with a README" when you created the repository.



              When master is really empty, I see the following options



              • go to gitlab, change the default branch to something else and remove the master branch in the web interface (there, it is possible to delete protected branches). Or,


              • unprotect master


              Now you can force-push your dev Branch to gitlab (e.g. git push -f dev:master).



              NOTE: this option is a no-go for branches resp. repositories which are used by other peoples. In this case do:



              git fetch gitlab master
              git merge -s ours FETCH_HEAD


              and push this branch.






              share|improve this answer













              You probably checked "[ ] Create repository with a README" when you created the repository.



              When master is really empty, I see the following options



              • go to gitlab, change the default branch to something else and remove the master branch in the web interface (there, it is possible to delete protected branches). Or,


              • unprotect master


              Now you can force-push your dev Branch to gitlab (e.g. git push -f dev:master).



              NOTE: this option is a no-go for branches resp. repositories which are used by other peoples. In this case do:



              git fetch gitlab master
              git merge -s ours FETCH_HEAD


              and push this branch.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Mar 25 at 23:39









              enscensc

              4,6769 silver badges15 bronze badges




              4,6769 silver badges15 bronze badges












              • For clarification is git fetch gitlab master and git merge -s ours FETCH_HEAD is executed from my master branch, correct?

                – Mix Master Mike
                Mar 25 at 23:50











              • git fetch can be executed everywhere (even in bare repositories). For git merge you have to checkout the branch which shall become master.

                – ensc
                Mar 25 at 23:54

















              • For clarification is git fetch gitlab master and git merge -s ours FETCH_HEAD is executed from my master branch, correct?

                – Mix Master Mike
                Mar 25 at 23:50











              • git fetch can be executed everywhere (even in bare repositories). For git merge you have to checkout the branch which shall become master.

                – ensc
                Mar 25 at 23:54
















              For clarification is git fetch gitlab master and git merge -s ours FETCH_HEAD is executed from my master branch, correct?

              – Mix Master Mike
              Mar 25 at 23:50





              For clarification is git fetch gitlab master and git merge -s ours FETCH_HEAD is executed from my master branch, correct?

              – Mix Master Mike
              Mar 25 at 23:50













              git fetch can be executed everywhere (even in bare repositories). For git merge you have to checkout the branch which shall become master.

              – ensc
              Mar 25 at 23:54





              git fetch can be executed everywhere (even in bare repositories). For git merge you have to checkout the branch which shall become master.

              – ensc
              Mar 25 at 23:54











              0














              You already fixed (?) this using --allow-unrelated-histories and there's no real reason not to just leave that. But in case you are still wondering...



              What happened, and how you (probably) got here



              The first key to using Git is to understand that Git is all about commits. Of course, this also requires that you understand, in a reasonably deep sort of way, what a commit is. What it is, is pretty short and simple: it's a permanent (mostly) and immutable (entirely) snapshot plus some metadata. The snapshot contains all of your files—well, all of them as of the time you made the commit—and the metadata has:



              • your name and email address, and the time you made the commit;

              • your log message, i.e., why you made this commit; and, crucially,

              • the hash ID of the commit that comes just before this commit, defined as the parent of this commit.

              Every commit is unique—for many reasons, including the time-stamp mentioned above—and every unique commit gets a unique hash ID. That hash ID, some big ugly string of hexadecimal characters, seems random, but is actually a cryptographic checksum of the contents of the commit. It's also the True Name, as it were, of that commit: that ID means that commit, and only that commit. No other commit will ever have that hash ID. That hash ID will always mean that commit.



              Git actually finds the commit by hash ID. So the hash ID is crucial. Of course, it's also impossible for humans to remember. So Git gives us a way to remember the latest hash ID, and that way is a branch name like master or dev.



              The name only has to remember the last commit because each commit remembers its parent's hash on its own. That is, given a tiny repository with just three commits, where we replace the actual hash IDs with a single uppercase letter, we can draw this:



              A <-B <-C <-- master


              The name master remembers the hash ID of C. C itself—the actual commit, retrieved by hash ID—remembers the hash ID of B, and B itself remembers the hash ID of A.



              When something remembers the hash ID of some other commit, we say that this something points to the commit. So the name master points to C, C points to B, and B points to A. Those three commits—C, then B, then Aare the history in the repository.



              Note that A doesn't point anywhere. It literally can't, because it was the first commit. There was no earlier commit. So it just doesn't, and Git calls this a root commit. All non-empty repositories have to have at least one root commit. Most, probably, have exactly one ... but yours has two.



              Normal branching and merging



              Let's take a quick look at the more normal way to make branches. Suppose we have just these three commits, pointed-to by master. We ask Git to make a new branch name, pointing to the same commit as master:



              A--B--C <-- dev (HEAD), master


              Both names identify commit C, so commit C is on—and is the tip commit of—both branches, and all three commits are on both branches. But now we make a new commit. The process of making a new commit—with the usual edit and git add and git commit—makes a new snapshot, adds our name and email and timestamp and so on, uses the current commit C as the saved hash, and builds the new commit. The new commit gets some big ugly hash ID, but we'll just call it D:



              A--B--C <-- dev (HEAD), master

              D


              Since D's parent is C, D points back to C. But now the magic happens: Git writes D's hash ID into the current branch name—the one HEAD is attached to—so now we have:



              A--B--C <-- master

              D <-- dev (HEAD)


              and voila, we have a new branch. (Well, we had it before, pointing to C. Most people don't like to think about it that way though, they want to call D the branch. In fact, the branch is D-C-B-A!)



              Over time we add some commits to both branches:



              A--B--C-----J----K----L <-- master

              D--E--F--G--H--I <-- dev


              We git checkout master and git merge dev. Git will find the merge base commit for us, where dev and master diverged. That's obviously commit C since that's where the two branches rejoin in the past. Git will compare C vs L to see what we changed on master, compare C vs I to see what we changed on dev, and combine the changes. Git applies the combined changes to the snapshot in C—to the merge base—and makes a new merge commit M, which goes on our current HEAD branch as usual, updating that branch name so that master points to M:



              A--B--C-----J----K----L--M <-- master (HEAD)
              /
              D--E--F--G--H--I <-- dev


              What's special about M is that it has two backwards links: it goes back to L, as all commits would, but it has a second parent I, which is the current tip commit of branch dev. Other than the two parents, though, it's quite ordinary: it has a snapshot as usual, and our name and email and timestamp and a log message.



              Abnormal branching



              There's nothing in Git that stops you from making extra root commits. It's just a little bit tricky. Suppose that, somehow, you did this:



              A <-- master

              B--C--D--...--L <-- dev (HEAD)


              Once you have this situation, git checkout master; git merge dev just gives you an error. That's because the usual method of finding a merge base—starting at the two branch tips and working backwards—never finds a common commit.



              Adding --allow-unrelated-histories tells Git to pretend that there's a special empty commit before both branches:



               A <-- master (HEAD)
              0
              B--C--D--...--L <-- dev


              Now Git can diff 0 vs A to see what you changed on master, and 0 vs L to see what they changed on dev. On master, you added every file. On dev, you also added every file. As long as those are different files, the way to combine those two changes is to add the master files from commit A to the dev files from commit L, apply those changes to the empty null commit, and commit the result, with parents going back to both A and L:



              A---------------M <-- master (HEAD)
              /
              B--C--D--...--L <-- dev


              How you (probably) got here



              There's a git checkout option, git checkout --orphan, that sets this state up. But that's probably not what you did. The state this sets up is the same state you're in when you create a new, empty repository with git init:



              [no commits] <-- [no branches]


              There are no branches, and yet Git will say that you're on branch master. You can't be on master: it doesn't exist. But you are, even though it doesn't exist. The way Git manages this is that it puts the name master into HEAD (.git/HEAD, actually) without first creating a branch named master. It can't create the branch because a branch name has to contain a valid hash ID, and there aren't any.



              So, when you run git commit, Git detects this anomalous state: that HEAD says master but master doesn't exist. That's what triggers Git to make our root commit A. Then Git writes A's hash ID into the branch, which creates the branch, and now we have:



              A <-- master (HEAD)


              which is just what we wanted.



              But suppose, while we're in this weird no-commits-yet state, we run:



              git checkout -b dev


              This tells Git: Put the name dev into HEAD. It does that without complaint, even though there's no master either. Then we make our first commit, but for no obvious reason, we'll pick B as its one-letter stand-in for its hash ID:



              B <-- dev (HEAD)


              Meanwhile, having run git init here, then git checkout -b dev, then done something and git commit, we'll go over to $WebHostingProvider—whether that's GitHub or GitLab or Bitbucket or whatever—and use its make me a new repository clicky buttons. Those usually have an option: create an initial commit with README and/or LICENSE files and such. If that option is checked—or the don't option is unchecked—they go ahead and make a first commit and a master:



              A <-- master (HEAD)


              Now you connect your repository to theirs and have your Git download any commits they have that you don't:



              A <-- origin/master

              B <-- dev (HEAD)


              You can now proceed to add lots of commits, never noticing that your dev branch is not related to their master branch (which your Git is calling origin/master).



              Later, you run:



              git checkout master


              Your Git notices that you don't have a master, but that you do have an origin/master. So your Git creates a master for you, pointing to the same commit as origin/master, and attaches your HEAD to your new master:



              A <-- master (HEAD), origin/master

              B--C--D--...--L <-- dev


              and voila, you're in the pickle you were in.






              share|improve this answer



























                0














                You already fixed (?) this using --allow-unrelated-histories and there's no real reason not to just leave that. But in case you are still wondering...



                What happened, and how you (probably) got here



                The first key to using Git is to understand that Git is all about commits. Of course, this also requires that you understand, in a reasonably deep sort of way, what a commit is. What it is, is pretty short and simple: it's a permanent (mostly) and immutable (entirely) snapshot plus some metadata. The snapshot contains all of your files—well, all of them as of the time you made the commit—and the metadata has:



                • your name and email address, and the time you made the commit;

                • your log message, i.e., why you made this commit; and, crucially,

                • the hash ID of the commit that comes just before this commit, defined as the parent of this commit.

                Every commit is unique—for many reasons, including the time-stamp mentioned above—and every unique commit gets a unique hash ID. That hash ID, some big ugly string of hexadecimal characters, seems random, but is actually a cryptographic checksum of the contents of the commit. It's also the True Name, as it were, of that commit: that ID means that commit, and only that commit. No other commit will ever have that hash ID. That hash ID will always mean that commit.



                Git actually finds the commit by hash ID. So the hash ID is crucial. Of course, it's also impossible for humans to remember. So Git gives us a way to remember the latest hash ID, and that way is a branch name like master or dev.



                The name only has to remember the last commit because each commit remembers its parent's hash on its own. That is, given a tiny repository with just three commits, where we replace the actual hash IDs with a single uppercase letter, we can draw this:



                A <-B <-C <-- master


                The name master remembers the hash ID of C. C itself—the actual commit, retrieved by hash ID—remembers the hash ID of B, and B itself remembers the hash ID of A.



                When something remembers the hash ID of some other commit, we say that this something points to the commit. So the name master points to C, C points to B, and B points to A. Those three commits—C, then B, then Aare the history in the repository.



                Note that A doesn't point anywhere. It literally can't, because it was the first commit. There was no earlier commit. So it just doesn't, and Git calls this a root commit. All non-empty repositories have to have at least one root commit. Most, probably, have exactly one ... but yours has two.



                Normal branching and merging



                Let's take a quick look at the more normal way to make branches. Suppose we have just these three commits, pointed-to by master. We ask Git to make a new branch name, pointing to the same commit as master:



                A--B--C <-- dev (HEAD), master


                Both names identify commit C, so commit C is on—and is the tip commit of—both branches, and all three commits are on both branches. But now we make a new commit. The process of making a new commit—with the usual edit and git add and git commit—makes a new snapshot, adds our name and email and timestamp and so on, uses the current commit C as the saved hash, and builds the new commit. The new commit gets some big ugly hash ID, but we'll just call it D:



                A--B--C <-- dev (HEAD), master

                D


                Since D's parent is C, D points back to C. But now the magic happens: Git writes D's hash ID into the current branch name—the one HEAD is attached to—so now we have:



                A--B--C <-- master

                D <-- dev (HEAD)


                and voila, we have a new branch. (Well, we had it before, pointing to C. Most people don't like to think about it that way though, they want to call D the branch. In fact, the branch is D-C-B-A!)



                Over time we add some commits to both branches:



                A--B--C-----J----K----L <-- master

                D--E--F--G--H--I <-- dev


                We git checkout master and git merge dev. Git will find the merge base commit for us, where dev and master diverged. That's obviously commit C since that's where the two branches rejoin in the past. Git will compare C vs L to see what we changed on master, compare C vs I to see what we changed on dev, and combine the changes. Git applies the combined changes to the snapshot in C—to the merge base—and makes a new merge commit M, which goes on our current HEAD branch as usual, updating that branch name so that master points to M:



                A--B--C-----J----K----L--M <-- master (HEAD)
                /
                D--E--F--G--H--I <-- dev


                What's special about M is that it has two backwards links: it goes back to L, as all commits would, but it has a second parent I, which is the current tip commit of branch dev. Other than the two parents, though, it's quite ordinary: it has a snapshot as usual, and our name and email and timestamp and a log message.



                Abnormal branching



                There's nothing in Git that stops you from making extra root commits. It's just a little bit tricky. Suppose that, somehow, you did this:



                A <-- master

                B--C--D--...--L <-- dev (HEAD)


                Once you have this situation, git checkout master; git merge dev just gives you an error. That's because the usual method of finding a merge base—starting at the two branch tips and working backwards—never finds a common commit.



                Adding --allow-unrelated-histories tells Git to pretend that there's a special empty commit before both branches:



                 A <-- master (HEAD)
                0
                B--C--D--...--L <-- dev


                Now Git can diff 0 vs A to see what you changed on master, and 0 vs L to see what they changed on dev. On master, you added every file. On dev, you also added every file. As long as those are different files, the way to combine those two changes is to add the master files from commit A to the dev files from commit L, apply those changes to the empty null commit, and commit the result, with parents going back to both A and L:



                A---------------M <-- master (HEAD)
                /
                B--C--D--...--L <-- dev


                How you (probably) got here



                There's a git checkout option, git checkout --orphan, that sets this state up. But that's probably not what you did. The state this sets up is the same state you're in when you create a new, empty repository with git init:



                [no commits] <-- [no branches]


                There are no branches, and yet Git will say that you're on branch master. You can't be on master: it doesn't exist. But you are, even though it doesn't exist. The way Git manages this is that it puts the name master into HEAD (.git/HEAD, actually) without first creating a branch named master. It can't create the branch because a branch name has to contain a valid hash ID, and there aren't any.



                So, when you run git commit, Git detects this anomalous state: that HEAD says master but master doesn't exist. That's what triggers Git to make our root commit A. Then Git writes A's hash ID into the branch, which creates the branch, and now we have:



                A <-- master (HEAD)


                which is just what we wanted.



                But suppose, while we're in this weird no-commits-yet state, we run:



                git checkout -b dev


                This tells Git: Put the name dev into HEAD. It does that without complaint, even though there's no master either. Then we make our first commit, but for no obvious reason, we'll pick B as its one-letter stand-in for its hash ID:



                B <-- dev (HEAD)


                Meanwhile, having run git init here, then git checkout -b dev, then done something and git commit, we'll go over to $WebHostingProvider—whether that's GitHub or GitLab or Bitbucket or whatever—and use its make me a new repository clicky buttons. Those usually have an option: create an initial commit with README and/or LICENSE files and such. If that option is checked—or the don't option is unchecked—they go ahead and make a first commit and a master:



                A <-- master (HEAD)


                Now you connect your repository to theirs and have your Git download any commits they have that you don't:



                A <-- origin/master

                B <-- dev (HEAD)


                You can now proceed to add lots of commits, never noticing that your dev branch is not related to their master branch (which your Git is calling origin/master).



                Later, you run:



                git checkout master


                Your Git notices that you don't have a master, but that you do have an origin/master. So your Git creates a master for you, pointing to the same commit as origin/master, and attaches your HEAD to your new master:



                A <-- master (HEAD), origin/master

                B--C--D--...--L <-- dev


                and voila, you're in the pickle you were in.






                share|improve this answer

























                  0












                  0








                  0







                  You already fixed (?) this using --allow-unrelated-histories and there's no real reason not to just leave that. But in case you are still wondering...



                  What happened, and how you (probably) got here



                  The first key to using Git is to understand that Git is all about commits. Of course, this also requires that you understand, in a reasonably deep sort of way, what a commit is. What it is, is pretty short and simple: it's a permanent (mostly) and immutable (entirely) snapshot plus some metadata. The snapshot contains all of your files—well, all of them as of the time you made the commit—and the metadata has:



                  • your name and email address, and the time you made the commit;

                  • your log message, i.e., why you made this commit; and, crucially,

                  • the hash ID of the commit that comes just before this commit, defined as the parent of this commit.

                  Every commit is unique—for many reasons, including the time-stamp mentioned above—and every unique commit gets a unique hash ID. That hash ID, some big ugly string of hexadecimal characters, seems random, but is actually a cryptographic checksum of the contents of the commit. It's also the True Name, as it were, of that commit: that ID means that commit, and only that commit. No other commit will ever have that hash ID. That hash ID will always mean that commit.



                  Git actually finds the commit by hash ID. So the hash ID is crucial. Of course, it's also impossible for humans to remember. So Git gives us a way to remember the latest hash ID, and that way is a branch name like master or dev.



                  The name only has to remember the last commit because each commit remembers its parent's hash on its own. That is, given a tiny repository with just three commits, where we replace the actual hash IDs with a single uppercase letter, we can draw this:



                  A <-B <-C <-- master


                  The name master remembers the hash ID of C. C itself—the actual commit, retrieved by hash ID—remembers the hash ID of B, and B itself remembers the hash ID of A.



                  When something remembers the hash ID of some other commit, we say that this something points to the commit. So the name master points to C, C points to B, and B points to A. Those three commits—C, then B, then Aare the history in the repository.



                  Note that A doesn't point anywhere. It literally can't, because it was the first commit. There was no earlier commit. So it just doesn't, and Git calls this a root commit. All non-empty repositories have to have at least one root commit. Most, probably, have exactly one ... but yours has two.



                  Normal branching and merging



                  Let's take a quick look at the more normal way to make branches. Suppose we have just these three commits, pointed-to by master. We ask Git to make a new branch name, pointing to the same commit as master:



                  A--B--C <-- dev (HEAD), master


                  Both names identify commit C, so commit C is on—and is the tip commit of—both branches, and all three commits are on both branches. But now we make a new commit. The process of making a new commit—with the usual edit and git add and git commit—makes a new snapshot, adds our name and email and timestamp and so on, uses the current commit C as the saved hash, and builds the new commit. The new commit gets some big ugly hash ID, but we'll just call it D:



                  A--B--C <-- dev (HEAD), master

                  D


                  Since D's parent is C, D points back to C. But now the magic happens: Git writes D's hash ID into the current branch name—the one HEAD is attached to—so now we have:



                  A--B--C <-- master

                  D <-- dev (HEAD)


                  and voila, we have a new branch. (Well, we had it before, pointing to C. Most people don't like to think about it that way though, they want to call D the branch. In fact, the branch is D-C-B-A!)



                  Over time we add some commits to both branches:



                  A--B--C-----J----K----L <-- master

                  D--E--F--G--H--I <-- dev


                  We git checkout master and git merge dev. Git will find the merge base commit for us, where dev and master diverged. That's obviously commit C since that's where the two branches rejoin in the past. Git will compare C vs L to see what we changed on master, compare C vs I to see what we changed on dev, and combine the changes. Git applies the combined changes to the snapshot in C—to the merge base—and makes a new merge commit M, which goes on our current HEAD branch as usual, updating that branch name so that master points to M:



                  A--B--C-----J----K----L--M <-- master (HEAD)
                  /
                  D--E--F--G--H--I <-- dev


                  What's special about M is that it has two backwards links: it goes back to L, as all commits would, but it has a second parent I, which is the current tip commit of branch dev. Other than the two parents, though, it's quite ordinary: it has a snapshot as usual, and our name and email and timestamp and a log message.



                  Abnormal branching



                  There's nothing in Git that stops you from making extra root commits. It's just a little bit tricky. Suppose that, somehow, you did this:



                  A <-- master

                  B--C--D--...--L <-- dev (HEAD)


                  Once you have this situation, git checkout master; git merge dev just gives you an error. That's because the usual method of finding a merge base—starting at the two branch tips and working backwards—never finds a common commit.



                  Adding --allow-unrelated-histories tells Git to pretend that there's a special empty commit before both branches:



                   A <-- master (HEAD)
                  0
                  B--C--D--...--L <-- dev


                  Now Git can diff 0 vs A to see what you changed on master, and 0 vs L to see what they changed on dev. On master, you added every file. On dev, you also added every file. As long as those are different files, the way to combine those two changes is to add the master files from commit A to the dev files from commit L, apply those changes to the empty null commit, and commit the result, with parents going back to both A and L:



                  A---------------M <-- master (HEAD)
                  /
                  B--C--D--...--L <-- dev


                  How you (probably) got here



                  There's a git checkout option, git checkout --orphan, that sets this state up. But that's probably not what you did. The state this sets up is the same state you're in when you create a new, empty repository with git init:



                  [no commits] <-- [no branches]


                  There are no branches, and yet Git will say that you're on branch master. You can't be on master: it doesn't exist. But you are, even though it doesn't exist. The way Git manages this is that it puts the name master into HEAD (.git/HEAD, actually) without first creating a branch named master. It can't create the branch because a branch name has to contain a valid hash ID, and there aren't any.



                  So, when you run git commit, Git detects this anomalous state: that HEAD says master but master doesn't exist. That's what triggers Git to make our root commit A. Then Git writes A's hash ID into the branch, which creates the branch, and now we have:



                  A <-- master (HEAD)


                  which is just what we wanted.



                  But suppose, while we're in this weird no-commits-yet state, we run:



                  git checkout -b dev


                  This tells Git: Put the name dev into HEAD. It does that without complaint, even though there's no master either. Then we make our first commit, but for no obvious reason, we'll pick B as its one-letter stand-in for its hash ID:



                  B <-- dev (HEAD)


                  Meanwhile, having run git init here, then git checkout -b dev, then done something and git commit, we'll go over to $WebHostingProvider—whether that's GitHub or GitLab or Bitbucket or whatever—and use its make me a new repository clicky buttons. Those usually have an option: create an initial commit with README and/or LICENSE files and such. If that option is checked—or the don't option is unchecked—they go ahead and make a first commit and a master:



                  A <-- master (HEAD)


                  Now you connect your repository to theirs and have your Git download any commits they have that you don't:



                  A <-- origin/master

                  B <-- dev (HEAD)


                  You can now proceed to add lots of commits, never noticing that your dev branch is not related to their master branch (which your Git is calling origin/master).



                  Later, you run:



                  git checkout master


                  Your Git notices that you don't have a master, but that you do have an origin/master. So your Git creates a master for you, pointing to the same commit as origin/master, and attaches your HEAD to your new master:



                  A <-- master (HEAD), origin/master

                  B--C--D--...--L <-- dev


                  and voila, you're in the pickle you were in.






                  share|improve this answer













                  You already fixed (?) this using --allow-unrelated-histories and there's no real reason not to just leave that. But in case you are still wondering...



                  What happened, and how you (probably) got here



                  The first key to using Git is to understand that Git is all about commits. Of course, this also requires that you understand, in a reasonably deep sort of way, what a commit is. What it is, is pretty short and simple: it's a permanent (mostly) and immutable (entirely) snapshot plus some metadata. The snapshot contains all of your files—well, all of them as of the time you made the commit—and the metadata has:



                  • your name and email address, and the time you made the commit;

                  • your log message, i.e., why you made this commit; and, crucially,

                  • the hash ID of the commit that comes just before this commit, defined as the parent of this commit.

                  Every commit is unique—for many reasons, including the time-stamp mentioned above—and every unique commit gets a unique hash ID. That hash ID, some big ugly string of hexadecimal characters, seems random, but is actually a cryptographic checksum of the contents of the commit. It's also the True Name, as it were, of that commit: that ID means that commit, and only that commit. No other commit will ever have that hash ID. That hash ID will always mean that commit.



                  Git actually finds the commit by hash ID. So the hash ID is crucial. Of course, it's also impossible for humans to remember. So Git gives us a way to remember the latest hash ID, and that way is a branch name like master or dev.



                  The name only has to remember the last commit because each commit remembers its parent's hash on its own. That is, given a tiny repository with just three commits, where we replace the actual hash IDs with a single uppercase letter, we can draw this:



                  A <-B <-C <-- master


                  The name master remembers the hash ID of C. C itself—the actual commit, retrieved by hash ID—remembers the hash ID of B, and B itself remembers the hash ID of A.



                  When something remembers the hash ID of some other commit, we say that this something points to the commit. So the name master points to C, C points to B, and B points to A. Those three commits—C, then B, then Aare the history in the repository.



                  Note that A doesn't point anywhere. It literally can't, because it was the first commit. There was no earlier commit. So it just doesn't, and Git calls this a root commit. All non-empty repositories have to have at least one root commit. Most, probably, have exactly one ... but yours has two.



                  Normal branching and merging



                  Let's take a quick look at the more normal way to make branches. Suppose we have just these three commits, pointed-to by master. We ask Git to make a new branch name, pointing to the same commit as master:



                  A--B--C <-- dev (HEAD), master


                  Both names identify commit C, so commit C is on—and is the tip commit of—both branches, and all three commits are on both branches. But now we make a new commit. The process of making a new commit—with the usual edit and git add and git commit—makes a new snapshot, adds our name and email and timestamp and so on, uses the current commit C as the saved hash, and builds the new commit. The new commit gets some big ugly hash ID, but we'll just call it D:



                  A--B--C <-- dev (HEAD), master

                  D


                  Since D's parent is C, D points back to C. But now the magic happens: Git writes D's hash ID into the current branch name—the one HEAD is attached to—so now we have:



                  A--B--C <-- master

                  D <-- dev (HEAD)


                  and voila, we have a new branch. (Well, we had it before, pointing to C. Most people don't like to think about it that way though, they want to call D the branch. In fact, the branch is D-C-B-A!)



                  Over time we add some commits to both branches:



                  A--B--C-----J----K----L <-- master

                  D--E--F--G--H--I <-- dev


                  We git checkout master and git merge dev. Git will find the merge base commit for us, where dev and master diverged. That's obviously commit C since that's where the two branches rejoin in the past. Git will compare C vs L to see what we changed on master, compare C vs I to see what we changed on dev, and combine the changes. Git applies the combined changes to the snapshot in C—to the merge base—and makes a new merge commit M, which goes on our current HEAD branch as usual, updating that branch name so that master points to M:



                  A--B--C-----J----K----L--M <-- master (HEAD)
                  /
                  D--E--F--G--H--I <-- dev


                  What's special about M is that it has two backwards links: it goes back to L, as all commits would, but it has a second parent I, which is the current tip commit of branch dev. Other than the two parents, though, it's quite ordinary: it has a snapshot as usual, and our name and email and timestamp and a log message.



                  Abnormal branching



                  There's nothing in Git that stops you from making extra root commits. It's just a little bit tricky. Suppose that, somehow, you did this:



                  A <-- master

                  B--C--D--...--L <-- dev (HEAD)


                  Once you have this situation, git checkout master; git merge dev just gives you an error. That's because the usual method of finding a merge base—starting at the two branch tips and working backwards—never finds a common commit.



                  Adding --allow-unrelated-histories tells Git to pretend that there's a special empty commit before both branches:



                   A <-- master (HEAD)
                  0
                  B--C--D--...--L <-- dev


                  Now Git can diff 0 vs A to see what you changed on master, and 0 vs L to see what they changed on dev. On master, you added every file. On dev, you also added every file. As long as those are different files, the way to combine those two changes is to add the master files from commit A to the dev files from commit L, apply those changes to the empty null commit, and commit the result, with parents going back to both A and L:



                  A---------------M <-- master (HEAD)
                  /
                  B--C--D--...--L <-- dev


                  How you (probably) got here



                  There's a git checkout option, git checkout --orphan, that sets this state up. But that's probably not what you did. The state this sets up is the same state you're in when you create a new, empty repository with git init:



                  [no commits] <-- [no branches]


                  There are no branches, and yet Git will say that you're on branch master. You can't be on master: it doesn't exist. But you are, even though it doesn't exist. The way Git manages this is that it puts the name master into HEAD (.git/HEAD, actually) without first creating a branch named master. It can't create the branch because a branch name has to contain a valid hash ID, and there aren't any.



                  So, when you run git commit, Git detects this anomalous state: that HEAD says master but master doesn't exist. That's what triggers Git to make our root commit A. Then Git writes A's hash ID into the branch, which creates the branch, and now we have:



                  A <-- master (HEAD)


                  which is just what we wanted.



                  But suppose, while we're in this weird no-commits-yet state, we run:



                  git checkout -b dev


                  This tells Git: Put the name dev into HEAD. It does that without complaint, even though there's no master either. Then we make our first commit, but for no obvious reason, we'll pick B as its one-letter stand-in for its hash ID:



                  B <-- dev (HEAD)


                  Meanwhile, having run git init here, then git checkout -b dev, then done something and git commit, we'll go over to $WebHostingProvider—whether that's GitHub or GitLab or Bitbucket or whatever—and use its make me a new repository clicky buttons. Those usually have an option: create an initial commit with README and/or LICENSE files and such. If that option is checked—or the don't option is unchecked—they go ahead and make a first commit and a master:



                  A <-- master (HEAD)


                  Now you connect your repository to theirs and have your Git download any commits they have that you don't:



                  A <-- origin/master

                  B <-- dev (HEAD)


                  You can now proceed to add lots of commits, never noticing that your dev branch is not related to their master branch (which your Git is calling origin/master).



                  Later, you run:



                  git checkout master


                  Your Git notices that you don't have a master, but that you do have an origin/master. So your Git creates a master for you, pointing to the same commit as origin/master, and attaches your HEAD to your new master:



                  A <-- master (HEAD), origin/master

                  B--C--D--...--L <-- dev


                  and voila, you're in the pickle you were in.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 26 at 0:16









                  torektorek

                  213k21 gold badges276 silver badges361 bronze badges




                  213k21 gold badges276 silver badges361 bronze badges



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55347352%2fwhy-cant-i-merge-my-git-dev-branch-to-master-even-though-master-only-contains-a%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                      Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                      Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript