क्या मैं ट्रैक की गई फ़ाइलों के बाहर .git फ़ोल्डर संग्रहीत कर सकता हूं?


147

मेरे पास बैकअप सिस्टम के रूप में गिट का उपयोग करने के लिए एक असामान्य विचार है। तो चलो कहते हैं कि मेरे पास एक निर्देशिका है ।/backup/myfiles और मैं git का उपयोग करके वापस चाहता हूं। चीजों को साफ रखने के लिए मुझे myfiles फ़ोल्डर में एक .git निर्देशिका नहीं चाहिए, इसलिए मैंने सोचा कि मैं बना सकता हूं ।/backup/git_repos/myfiles। Git डॉक्स को देखने से, मैंने यह करने की कोशिश की है:

$ cd backup/myfiles
$ mkdir ../git_repos/myfiles
$ git --git-dir=../git_repos/myfiles init
Initialized empty Git repository in backup/git_repos/myfiles/
$ git --git-dir="../git_repos/myfiles/" add foo
fatal: pathspec 'foo' did not match any files

आप मुझे मिलने वाले त्रुटि संदेश को देख सकते हैं। मैं क्या गलत कर रहा हूं?


9
अपने बैकअप आइडिया के साथ-साथ, इसका इस्तेमाल अपने "डॉटफाइल्स" (.bashrc, .vimrc, आदि) को होम डायरेक्टरी में कहीं और .it फोल्डर को रखने के लिए भी किया जा सकता है।
फिलिप

6
सबसे स्पष्ट जवाब: stackoverflow.com/a/19548676/170352 (पुराने उठाव के कारण दफन)
ब्रैंडन बर्टेल्सन

1
इस मामले में कि आपके पास कोई लेखन पहुंच नहीं है या काम करने वाली निर्देशिका में कोई बदलाव नहीं करना चाहते हैं (जैसे। अगस्त / आदि), लियो द्वारा नीचे दिया गया यह उत्तर (पुराने अपवोट द्वारा दफन भी) सबसे अच्छा है।
कोबजोहन

1
@Philip, जब तक कि आपके dotfiles रिपॉजिटरी में Git सबमॉड्यूल भी नहीं होते हैं। Git बाह्य कार्य ट्री के साथ संयोजन में सबमॉड्यूल का समर्थन नहीं करता है।
मैक्सक्लेपज़िग

जवाबों:


101
git --git-dir=../repo --work-tree=. add foo

यह वही करेगा जो आप चाहते हैं लेकिन स्पष्ट रूप से तब चूसना होगा जब आपको इसे हर उस कमांड के साथ निर्दिष्ट करना होगा जिसे आप कभी भी उपयोग करते हैं।

आप निर्यात कर सकते हैं GIT_WORK_TREE=.और GIT_DIR=../backupऔर Git प्रत्येक आदेश पर उन्हें लेने होंगे। यह केवल आराम से आपको प्रति शेल एकल भंडार में काम करने की अनुमति देगा, हालांकि।

मैं बजाय कहीं और .IT निर्देशिका से सहानुभूति रखने का सुझाव दूंगा या अपने मुख्य बैकअप निर्देशिका से .IT निर्देशिका के लिए एक सिम्लिंक बनाना चाहूंगा।


1
आप प्रत्येक कमांड में git-dir और वर्क-ट्री को निर्दिष्ट किए बिना और बिना किसी प्रतीकात्मक लिंक के समान संग्रह कर सकते हैं। मेरा जवाब देखिए।
niks

एक सिम्लिंक का नकारात्मक पक्ष यह है कि यह काम के पेड़ के भीतर मौजूद है, और यदि कोई अन्य प्रक्रिया काम के पेड़ को मिटा देती है, तो आप सिमिलिंक खो चुके हैं
जेफ

इसके अलावा, अगर ओपी अपने काम के पेड़ में एक .it सबडायरेक्ट्री नहीं चाहता था, तो वह एक सिमलिंक क्यों चाहेगा?
जेफ

@ जेफ़: एक व्यापार बंद के लिए। (उनके बैकअप के मामले में, अपने काम के पेड़ को पोंछना शायद उनके लिए किसी भी अन्य डायर (जैसे रेपो ही) को मिटा देने की तुलना में कोई बड़ी चिंता नहीं है।)
एसजेड।

1
मैं अपने नोट्स के लिए direnv के साथ इसका उपयोग कर रहा हूं । मेरा काम करने वाला पेड़ ड्रॉपबॉक्स में एक फ़ोल्डर में है और मेरा गिट फ़ोल्डर कहीं बाहर है। इस तरह से मैं आसानी से सभी कंप्यूटरों पर अपने बदलाव कर सकता हूं, लेकिन फिर भी यह जांचने में सक्षम हो सकता हूं कि क्या बदल गया है और केवल तभी प्रतिबद्ध है जब कुछ महत्वपूर्ण बदल गया हो। धन्यवाद
पाउलो Phagula

170

आपको बस यह सुनिश्चित करने की आवश्यकता है कि रिपॉजिटरी को पता है कि काम का पेड़ कहां है और इसके विपरीत।

रिपॉजिटरी को यह बताने के लिए कि वर्क ट्री कहाँ है, कॉन्फ़िगरेशन मान सेट करें core.worktree। कार्य ट्री को यह बताने के लिए कि वह कहाँ है, यह git डाइरेक्टरी है, .it नाम की फ़ाइल जोड़ें (फ़ोल्डर नहीं!) और एक पंक्ति जोड़ें

gitdir: /path/to/repo.git

चूंकि git 1.7.5 init कमांड ने इसके लिए एक अतिरिक्त विकल्प सीखा है।

आप के साथ एक नया अलग भंडार शुरू कर सकते हैं

git init --separate-git-dir /path/to/repo.git

यह अलग-अलग डायरेक्टरी में git रिपॉजिटरी को इनिशियलाइज़ करेगा और वर्तमान डायरेक्टरी में .it फ़ाइल को जोड़ेगा, जो नए रिपॉजिटरी की वर्किंग डायरेक्टरी है।

पहले 1.7.5 के लिए आपको कुछ अलग मापदंडों का उपयोग करना था और .git फ़ाइल को स्वयं जोड़ना था।

एक अलग रिपॉजिटरी को इनिशियलाइज़ करने के लिए निम्न कमांड रिपोजिटरी के साथ कार्य-वृक्ष को जोड़ता है:

git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git

आपकी वर्तमान निर्देशिका वर्किंग ट्री होगी और git रिपॉजिटरी का उपयोग करेगा /path/to/repo.git। इनिट कमांड स्वचालित core.worktreeरूप से --git-dirपैरामीटर के साथ निर्दिष्ट मान को सेट करेगा ।

आप इसके लिए एक उपनाम भी जोड़ सकते हैं:

[alias]
    initexternal = !"f() { git --work-tree=. --git-dir=\"$1\" init && echo \"gitdir: $1\" >> .git; }; f"

रीड-ओनली वर्किंग डायरेक्टरी पर git वर्जन कंट्रोल का उपयोग करें

ऊपर दिए गए ज्ञान के साथ, आप लेखन अनुमति के बिना किसी कार्यशील निर्देशिका के लिए git संस्करण नियंत्रण भी सेट कर सकते हैं। यदि आप या तो --git-dirहर git कमांड पर उपयोग करते हैं या रिपॉजिटरी (वर्किंग डायरेक्टरी के बजाय) से हर कमांड को निष्पादित करते हैं, तो आप .गित फ़ाइल को छोड़ सकते हैं और इसलिए वर्किंग डायरेक्टरी के भीतर किसी भी फाइल को बनाने की आवश्यकता नहीं है। Leos जवाब भी देखें


7
आप इसे किसी मौजूदा रेपो में भी कर सकते हैं: .it फ़ोल्डर को जहाँ चाहें वहाँ ले जाएँ, इसे इंगित करने के लिए .it फ़ाइल जोड़ें, और फिर आप बस रेपो का उपयोग कर सकते हैं जैसा कि आप सामान्य रूप से करेंगे
joachim

ध्यान दें कि आप केवल अपने रेपो की जड़ से git कमांड जारी कर सकते हैं। सबफ़ोल्डर्स में जाना इसे भ्रमित करता है! (ऐसा होता है कि क्या gitdir के लिए दिए गए मान सापेक्ष या निरपेक्ष हैं या नहीं।)
joachim

2
इसके लिए फिक्स वास्तविक git config फाइल में 'core.worktree' को निर्दिष्ट करना है, अर्थात फ़ोल्डर में एक। Init को इंगित करता है।
जोचिम

2
हां, यही मैंने अपने उत्तर के दूसरे वाक्य में वर्णित किया है। कॉन्फ़िगरेशन मान core.worktreeनिश्चित रूप से .it फ़ोल्डर की कॉन्फ़िगरेशन फ़ाइल में संग्रहीत होता है, .it फ़ाइल बिंदुओं को wherer करता है।
निक्स

1
मुझे लगता है कि जब मैंने इन निर्देशों का उपयोग किया तो रेपो बनाना एक नंगे भंडार बन गया और यह त्रुटि देता है fatal: core.worktree and core.bare do not make sense। लगता है जैसे यह सिर्फ विन्यास बदल रहा है तो यह नंगे हल नहीं है कि।
स्टीवन लू

62

--separate-git-dirके लिए विकल्प git init(और git clone) Git के अपने संस्करण (पर यह पूरा करने के लिए किया जा सकता 1.7.11.3)। विकल्प कार्य ट्री से गिट रिपॉजिटरी को अलग करता है और काम के पेड़ .gitकी जड़ में एक फाइलसिस्टम एग्नॉस्टिक गिट प्रतीकात्मक लिंक (नाम के रूप में फ़ाइल ) बनाता है । मुझे लगता है कि परिणाम निक्स के जवाब के समान है ।

git init --separate-git-dir path/to/repo.git path/to/worktree

2
+1 initअपने लिए एक कमांड लाइन विकल्प का उपयोग करना स्पष्ट और साफ दिखता है
goncalopp

विंडोज़ में, repo.gitइसके हेडेन विशेषता सेट के साथ बनाया गया है। मैं तो इसे मैन्युअल रूप से बदलता हूं। क्या आपको पता है कि क्या यह सुरक्षित है?
पीए

+1 Yes git ने इस कमांड लाइन विकल्प को 1.7.5 संस्करण में झुकाव दिया, जो तब उपलब्ध नहीं था (यदि मुझे सही याद है)। मैंने इस पैरामीटर का उपयोग करने के लिए सुझाव देने के लिए अपना उत्तर अपडेट कर दिया है।
niks

25

मुझे niks के उत्तर में प्रयुक्त --work-treeऔर --git-dirनिर्देशिकाओं को उल्टा करना सरल लगता है :

$ cd read_only_repos
$ git --work-tree=/some/readonly/location/foo/ --git-dir=foo init
$ cd foo
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .file_foo
        bar
        ...

इस दृष्टिकोण के दो फायदे हैं:

  • यह किसी भी कमांड-लाइन विकल्प या .gitफ़ाइलों की आवश्यकता को हटा देता है । आप बस आम तौर पर भंडार की जड़ के भीतर से काम करते हैं।
  • यह आपको एक फ़ाइल सिस्टम को संस्करण करने की अनुमति देता है, भले ही आप इसके मालिक न हों। Git केवल रिपॉजिटरी लोकेशन पर लिखेगा।

मेरे द्वारा सामना किया गया एकमात्र चेतावनी यह है कि किसी .gitignoreफ़ाइल का उपयोग करने के बजाय , आप संपादित करते हैं info/exclude

फिर आप read_only_repos/fooअपने स्वयं के रिपॉजिटरी में रिमोट के रूप में रिपॉजिटरी का उपयोग कर सकते हैं, भले ही मूल फाइलें संस्करण नियंत्रण में न हों।


वैसे यह बिल्कुल वही कमांड है। एकमात्र अंतर जो मुझे दिखाई देता है वह यह है कि आपने --वर्क-ट्री और --गित-दिर तर्कों के आदेश को स्वैप किया। और निश्चित रूप से आप कार्य निर्देशिका में .it फ़ाइल नहीं बनाते हैं क्योंकि आपके पास इसकी पहुंच नहीं है। फिर भी, एक निर्देशिका के लिए संस्करण नियंत्रण का उपयोग किए बिना लिखने का उपयोग करना एक अच्छा उपयोग मामला है। :-)
niks

3
आपको यह मिला। कुंजी वर्किंग डायरेक्टरी के बाहर रेपो बना रही है।
सिंह

4
मुझे यह पसंद है - यह मुझे उन निर्देशिकाओं पर गिट का उपयोग करने की अनुमति देता है जिन्हें मैं ड्रॉपबॉक्स के साथ साझा कर रहा हूं, अन्य प्रतिभागियों के बिना भी गिट का उपयोग करने की जानकारी है।
क्वेंटिन स्टैफोर्ड-फ्रेजर

19

यह एक निर्देशिका का नाम देने के लिए पारंपरिक है जो एक गिट रिपॉजिटरी है जिसका एक असामान्य स्थान में '.git' एक्सटेंशन है, जो नंगे भंडार की तरह है।

mkdir ../git_repos/myfiles.git

यदि आपने --work-treeinit समय पर विकल्प प्रदान किया था, तो यह स्वतः ही core.worktreeपरिवर्तनशील चर को सेट कर देता है, जिसका अर्थ है कि git को पता होगा कि git डाइरेक्टरी को निर्दिष्ट करने के बाद काम करने वाले पेड़ को कहाँ खोजें।

git --git-dir=../git_repos/myfiles.git --work-tree=. init

लेकिन आप इस चर को तथ्य के बाद भी सेट कर सकते हैं।

git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"

एक बार जब आप ऐसा कर लेते हैं, तो ऐड कमांड को उम्मीद के मुताबिक काम करना चाहिए।

git --git-dir=../git_repos/myfiles.git add foo

मैंने पाया है कि यदि आप cd ../git_repos/myfiles.git पर जाएं, तो वास्तविक कार्य ट्री में होने के बजाय, 'git add foo' सिर्फ काम करेगा, और आपको --git-dir को निर्दिष्ट करने की आवश्यकता नहीं है समय।
स्टीव फ़ॉली

1
यह सच है, लेकिन मुझे लगता है कि ज्यादातर लोग अपने रिपॉजिटरी के बजाय अपने काम के पेड़ में काम करते हैं। बेशक, यदि आप एक अलग काम कर रहे पेड़ का उपयोग कर रहे हैं, तो आप शायद कुछ 'विशेष' कर रहे हैं और मदद करने के लिए कुछ मैक्रोज़ का उपयोग कर सकते हैं।
CB Bailey

6

gitरेपो के अंदर उपयोग करें :

cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false

अब से, आप किसी भी पर्यावरण चर या अतिरिक्त मापदंडों को निर्धारित किए बिना, निर्देशिका के gitअंदर उपयोग कर सकते हैं ./backup/git_repos/myfiles


यह सबसे अच्छा उत्तर की तरह लगता है, लेकिन मुझे संदेश मिलता warning: core.bare and core.worktree do not make senseहै कि इसका मतलब यह नहीं है कि यह काम नहीं किया है?
खतरों के खिलाड़ी

1
मुझे अभी भी लगता है कि काम करता है, लेकिन यह वर्कट्री सेट करते समय नंगे होने की शिकायत करता है। इसलिए मैं बाद में सेट core.bareकर रहा हूं false
1

आह! यह अब अधिक समझ में आता है। उसके लिए धन्यवाद।
खतरों के खिलाड़ी

1

आप कुछ के साथ एक "नोडिट" स्क्रिप्ट (कोई डॉट जीआईटी) बना सकते हैं

#!/bin/sh
gits=/usr/local/gits
    x=`pwd`
    testdir() {( cd $1; pwd; )}
    while [ "$x" != "/" ]; do
      y=`echo $x|sed -e "s/\//__/g"`
      if ([ -d "$gits/$y" ]); then
        export GIT_DIR="$gits/$y"
        export GIT_WORK_TREE="$x"
        if ([ "$1" = "nodinit" ]); then
          mkdir -p "$GIT_DIR"
          git init --bare; exit $?
        elif ([ "$1" = "shell" ]); then
          bash; exit $?
        else
          exec git "$@"
        fi
      fi
      x=`testdir "$x/.."`
    done

आप git के स्थान पर nodgit को कॉल कर सकते हैं और यह git repo की तलाश में वैरिएबल को आवश्यकतानुसार सेट करेगा। उदाहरण के लिए, आपके पास / नंगे (रेपियर) रेपो / usr / लोकल / गिट्स / __ home__foo_wibbles में हैं और आप / होम / फू / वाइबल्स / एक में हैं, तो यह सही वर्किंग डायरेक्टरी (/ होम / फू / वाइबल्स) और रेपो ढूंढेगा ।

ओह, आप सही नोड्स सेट के साथ एक शेल प्राप्त करने के लिए "नोडोडिट शेल" का उपयोग कर सकते हैं ताकि आप सादे पुराने गिट कमांड का उपयोग कर सकें।


0

मान लें कि आपकी myfilesनिर्देशिका पहले से मौजूद है और कुछ सामग्री है, तो क्या आप इसके साथ रह सकते हैं:

cd ~/backup
git init
git add myfiles

.gitनिर्देशिका में हो जाएगा backupनहीं है, myfiles


हालाँकि, जो मैं चाहता था उसे ठीक करूँगा, मैं सिर्फ git के तहत myfiles फ़ोल्डर को स्टोर करूँगा, और कुछ नहीं।
रोरी

आप उन फ़ाइलों का चयन रख सकते हैं जिन्हें आप फ़ाइल gitका उपयोग करके ट्रैक करना चाहते हैं .gitignore। यदि आप इसे जोड़ते हैं *और !myfilesइसे करते हैं, तो केवल उस निर्देशिका को ट्रैक किया जाएगा। लेकिन अगर आप किसी अन्य निर्देशिका के लिए एक अलग रेपो चाहते हैं, तो आपको एक समस्या होगी ...
To1ne

0

मैं ऐसी स्क्रिप्ट्स बनाता हूं जो दिखती हैं

~ / Bin / Git-स्लैश:

#!/usr/bin/sh

export GIT_DIR=/home/Version-Control/cygwin-root.git/
export GIT_WORK_TREE=/

git --git-dir=$GIT_DIR --work-tree=$GIT_WORK_TREE "$@"

exit $?

यह उपयोग करने के लिए बेमानी है --गित_डिर = $ GIT_DIR, लेकिन मुझे याद दिलाता है कि मैं स्क्रिप्ट के बाहर पर्यावरण चर भी सेट कर सकता हूं।

उपर्युक्त उदाहरण साइबर परिवर्तन प्रणाली फ़ाइलों में स्थानीय परिवर्तनों को ट्रैक करने के लिए है।

किसी भी बड़े प्रोजेक्ट के लिए एक ऐसी स्क्रिप्ट बना सकते हैं जिसकी जरूरत हो - लेकिन / without /.it मेरा मुख्य उपयोग है।

यदि आप अतिरेक को समाप्त करते हैं, तो शेल उर्फ ​​या फ़ंक्शन बनाने के लिए उपरोक्त छोटा है।

अगर मैं अक्सर ऐसा करता हूं, तो मैं कार्यक्षेत्र को पुनर्जीवित करने के लिए रिपॉजिटरी मैपिंग करूंगा

"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System", 
in Workshop Proceedings of the Software Management Conference. 1989.

जिसका निकटतम आधुनिक समकक्ष पेरफोर्स मैपिंग या विचार है , आंशिक चेकआउट के साथ-साथ कार्यक्षेत्र और रेपो के गैर-उपनिवेशवाद का समर्थन करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.