How to convert a normal Git repository to a bare one?

后端 未结 17 983
礼貌的吻别
礼貌的吻别 2020-11-22 08:05

How can I convert a \'normal\' Git repository to a bare one?

The main difference seems to be:

  • in the normal Git repository, you have a .git

相关标签:
17条回答
  • 2020-11-22 08:17

    In short: replace the contents of repo with the contents of repo/.git, then tell the repository that it is now a bare repository.

    To do this, execute the following commands:

    cd repo
    mv .git ../repo.git # renaming just for clarity
    cd ..
    rm -fr repo
    cd repo.git
    git config --bool core.bare true
    

    Note that this is different from doing a git clone --bare to a new location (see below).

    0 讨论(0)
  • 2020-11-22 08:17

    Please also consider to use

    git clone --mirror path_to_source_repository
    

    From the documentation:

    Set up a mirror of the source repository. This implies --bare. Compared to --bare, --mirror not only maps local branches of the source to local branches of the target, it maps all refs (including remote-tracking branches, notes etc.) and sets up a refspec configuration such that all these refs are overwritten by a git remote update in the target repository.

    0 讨论(0)
  • 2020-11-22 08:23

    Oneliner for doing all of the above operations:

    for i in `ls -A .`; do if [ $i != ".git" ]; then rm -rf $i; fi; done; mv .git/* .; rm -rf .git; git config --bool core.bare true
    

    (don't blame me if something blows up and you didn't have backups :P)

    0 讨论(0)
  • 2020-11-22 08:24

    I used the following script to read a text file that has a list of all my SVN repos and convert them to GIT, and later use git clone --bare to convert to a bare git repo

    #!/bin/bash
    file="list.txt"
    while IFS= read -r repo_name
    do
     printf '%s\n' "$repo_name"
     sudo git svn clone --shared --preserve-empty-dirs --authors-file=users.txt file:///programs/svn/$repo_name 
     sudo git clone --bare /programs/git/$repo_name $repo_name.git
     sudo chown -R www-data:www-data $repo_name.git
     sudo rm -rf $repo_name
    done <"$file"
    

    list.txt has the format

    repo1_name
    repo2_name
    

    and users.txt has the format

    (no author) = Prince Rogers <prince.rogers.nelson@payesley.park.org>

    www-data is the Apache web server user, permission is needed to push changes over HTTP

    0 讨论(0)
  • 2020-11-22 08:27

    Here is the definition of a bare repository from gitglossary:

    A bare repository is normally an appropriately named directory with a .git suffix that does not have a locally checked-out copy of any of the files under revision control. That is, all of the Git administrative and control files that would normally be present in the hidden .git sub-directory are directly present in the repository.git directory instead, and no other files are present and checked out. Usually publishers of public repositories make bare repositories available.

    I arrived here because I was playing around with a "local repository" and wanted to be able to do whatever I wanted as if it were a remote repository. I was just playing around, trying to learn about git. I'll assume that this is the situation for whoever wants to read this answer.

    I would love for an expert opinion or some specific counter-examples, however it seems that (after rummaging through some git source code that I found) simply going to the file .git/config and setting the core attribute bare to true, git will let you do whatever you want to do to the repository remotely. I.e. the following lines should exist in .git/config:

    [core]
        ...
        bare = true
    ...
    

    (This is roughly what the command git config --bool core.bare true will do, which is probably recommended to deal with more complicated situations)

    My justification for this claim is that, in the git source code, there seems to be two different ways of testing if a repo is bare or not. One is by checking a global variable is_bare_repository_cfg. This is set during some setup phase of execution, and reflects the value found in the .git/config file. The other is a function is_bare_repository(). Here is the definition of this function:

    int is_bare_repository(void)
    {
        /* if core.bare is not 'false', let's see if there is a work tree */
        return is_bare_repository_cfg && !get_git_work_tree();
    } 
    

    I've not the time nor expertise to say this with absolute confidence, but as far as I could tell if you have the bare attribute set to true in .git/config, this should always return 1. The rest of the function probably is for the following situation:

    1. core.bare is undefined (i.e. neither true nor false)
    2. There is no worktree (i.e. the .git subdirectory is the main directory)

    I'll experiment with it when I can later, but this would seem to indicate that setting core.bare = true is equivalent to removeing core.bare from the config file and setting up the directories properly.

    At any rate, setting core.bare = true certainly will let you push to it, but I'm not sure if the presence of project files will cause some other operations to go awry. It's interesting and I suppose instructive to push to the repository and see what happened locally (i.e. run git status and make sense of the results).

    0 讨论(0)
  • 2020-11-22 08:31

    First, backup your existing repo:

    (a)  mkdir backup
    
    (b)  cd backup
    
    (c)  git clone non_bare_repo
    

    Second, run the following:

    git clone --bare -l non_bare_repo new_bare_repo
    
    0 讨论(0)
提交回复
热议问题