5

We had a Gitlab CE on a vm in our server.
There were 3 people working on a single repository on this Gitlab server.
This Gitlab CE vm has been deleted accidentally! These 3 people still have their local repositories with a lot of branches.
Our branching strategy was like this:
We had a Master branch and some feature branches per user.
users used to:

  • pull master from remote,
  • make a branch from it,
  • make changes,
  • push to master again (via merge requests)

Now, I have some questions:

  1. Is there any way-strategy to recreate-rebuild remote repo from local ones?
  2. If not, what should I do to create another remote repo and merge all commits to it?
MeeDNite
  • 159
  • 3
  • 13

4 Answers4

7
  • Create an empty repo in GitLab/BitBucket/GitHub.

  • Add a new remote (say, another) in your current repo with the URL of the new repo. Then push your master branch commits/changes to another repo's master branch.

    $ git remote add another <new-repo-url>
    $ git remote -v                 # see if the remote is added correctly 
    $ git checkout master
    
    $ git push another master       # push the changes to another/master
    
  • If you need features of another branch (say, feature) then simply checkout to the feature branch and push the changes to another repo's feature branch.

    $ git checkout feature
    $ git push another feature      # push changes to 'another' repo's 'feature' branch
    
  • Push all the branches and tags to another repo.

    $ git push --all --tags another
    

N.B. Here, another represents your new repo's URL.

Sajib Khan
  • 22,878
  • 9
  • 63
  • 73
  • Thanks for answer. Our users were at different states (commits) of the master branch. which one should push to master? and what about other feature branches? – MeeDNite Feb 25 '17 at 07:56
  • If you need to push other features (of another branch) then, `checkout` to that branch and push `git push another ` simply. Updated answer. – Sajib Khan Feb 25 '17 at 07:59
  • Im trying this now. pray for me! – MeeDNite Feb 25 '17 at 08:05
  • You can simplify the initial restoration with `git push --all --tags`, or, if the re-created server can make outgoing connections to one of the clients, `git clone --bare` from any one of the various clients (i.e., put the client in server role for a moment). But note that this publishes everything! @MeeDNite: since different users had different amounts of progress.. well, I can write a long answer if you like, but it amounts to, you want to make a union of all sets of public commits, and branch-and-tag-names. Your best bet is to start with the "most complete" user, whoever that is. – torek Feb 25 '17 at 17:36
3

Since your remote was deleted you don't have any origin yet so you will have to checkout the "remote" branches locally and assign them the original name and than push all the branches to the remote.

If you dont want the local branches simply push the ones you need.

Here is a scrip which im using to checkout all branches and than push them to the new remote

#!/bin/bash

# add the new origin 
git remote add origin2 <url>

# loop over all the original branches and set the new remote as the new track origin
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
    git branch --track ${branch#remotes/origin2/} $branch
done

# now push all branches and tags
git push origin2 --all    
git push origin2 --tags

What does the script do?

git branch -a
get a list of all the local branches

| grep remotes The branch names are : 'remotes/origin/' so this will remove the remotes from the branch names

| grep -v HEAD | grep -v master
remove the master (current branch) and HEAD which is an alias to the latest commit

Community
  • 1
  • 1
CodeWizard
  • 128,036
  • 21
  • 144
  • 167
  • Nice script! One thing I'm confused if `| grep remotes` should be `| grep -v remotes` to invert (remove the remotes) here? – Sajib Khan Feb 25 '17 at 08:24
  • Nope. we search for **all the remotes** only since all the local ones are already checkout, the remotes is to search for remotes and the `-v` is to remove the `HEAD` & `master` – CodeWizard Feb 25 '17 at 08:38
  • Ok. Thanks. Actually, I was messed up the line: " 'remotes/origin/' so this will **remove** the remotes..." – Sajib Khan Feb 25 '17 at 08:45
  • 1
    Note that if you already have a local branch X with origin/X as its upstream, the `git branch --track` command will fail. That's OK as long as your local branch `X` is reasonably up to date, although in this particular case, I'd actually start a bit differently. This also assumes only one remote, and scripts should use `git for-each-ref` rather than `git branch -a` here, and there are some additional possible refinements, but overall this is a pretty good way to go about it. – torek Feb 25 '17 at 17:55
  • I agree, this script is for a single repo and for local branches. Thanks for pointing it all out. – CodeWizard Feb 25 '17 at 18:00
2

You can copy (or clone --bare) one of the local repositories and rebase/delete the commits that weren't merged to the remote repo. After that you can use this one as remote.

Niklas P
  • 3,427
  • 2
  • 15
  • 19
  • This way we lose not-merged commits. they're important. – MeeDNite Feb 25 '17 at 07:59
  • No, you only temporarily lose the not-merged commits within the remote repo. There's no problem to push them from the cloned local repository the way you standardly push to the remote repo. – Niklas P Feb 25 '17 at 08:02
  • Depending on who had what in which repository and how easy it is to make a client act as a server briefly, this is how I would do it. Note that, on the server-acting-as-client-temporarily, after you `git clone --bare --mirror` one of the clients-acting-as-server, you probably want to `git remote delete origin` so that you don't leave the server's clone looking like a client (but that's more a tidiness issue than a correctness one). – torek Feb 25 '17 at 17:39
  • 1
    I should also add that, as in CodeWizard's script, you probably want to set up local branch names for all the remote-tracking branches you have. – torek Feb 25 '17 at 17:53
0

I accidentally deleted my branch on "origin". But I still had a local copy. Here's how I recreated the branch on "origin":

When I switched to the local copy, I saw this message:

Switched to branch 'my-special-branch'
Your branch is based on 'origin/my-special-branch', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

I used:

git branch --unset-upstream

That got the branch back to a normal unpushed state. To get it back on origin, I just ran

git push --set-upstream origin my-special-branch
Jean Libera
  • 549
  • 4
  • 8