কীভাবে গিট সাবডাইরেক্টরিটি এক্সট্রাক্ট করতে হবে এবং এর থেকে সাবমডিউল কীভাবে তৈরি করা যায়?


119

আমি কয়েক মাস আগে একটি প্রকল্প শুরু করেছি এবং সমস্ত কিছু একটি মূল ডিরেক্টরিতে সঞ্চয় করেছি। আমার মূল ডিরেক্টরিতে "প্রকল্প" তে বিভিন্ন জিনিস সম্বলিত বেশ কয়েকটি সাব-ডাইরেক্টরি রয়েছে: প্রজেক্ট / কাগজে লটেক্স প্রজেক্ট / সোর্সকোড / রেলস অ্যাপে লিখিত একটি নথি থাকে যা আমার রেল অ্যাপ্লিকেশন ধারণ করে।

"প্রকল্প" GITified এবং "কাগজ" এবং "রেলস অ্যাপ" ডিরেক্টরি উভয়তেই প্রচুর কমিট হয়েছে। এখন, আমি যেমন আমার "রেইলস অ্যাপ" এর জন্য ক্রুয়েসেকন্ট্রোল.আরবি ব্যবহার করতে চাই, আমি অবাক হয়েছি যে ইতিহাসটি না হারিয়ে "রেলস অ্যাপ" থেকে সাব-মডিউল তৈরির উপায় আছে কিনা?


2
এছাড়াও একটি খুব ভাল উত্তর: stackoverflow.com/questions/359424/...
Rehno Lindeque

উত্তর:


122

আজকাল গিট ফিল্টার-শাখা: গিট সাবট্রি ব্যবহারের চেয়ে ম্যানুয়ালি এটি করার আরও অনেক সহজ উপায় রয়েছে

স্থাপন

দ্রষ্টব্য git-subtree এখন git1.7.11 হিসাবে (আপনি যদি অবদান ইনস্টল করেন) এর অংশ, সুতরাং আপনার এটি ইতিমধ্যে ইনস্টল থাকতে পারে। আপনি নির্বাহ করে পরীক্ষা করতে পারেন git subtree


উত্স থেকে গিট-সাবট্রি ইনস্টল করতে (গিটের পুরানো সংস্করণগুলির জন্য):

git clone https://github.com/apenwarr/git-subtree.git

cd git-subtree
sudo rsync -a ./git-subtree.sh /usr/local/bin/git-subtree

অথবা আপনি যদি ম্যান পেজ এবং সমস্ত চান

make doc
make install

ব্যবহার

একটি বৃহত্তর ছোট অংশে বিভক্ত করুন:

# Go into the project root
cd ~/my-project

# Create a branch which only contains commits for the children of 'foo'
git subtree split --prefix=foo --branch=foo-only

# Remove 'foo' from the project
git rm -rf ./foo

# Create a git repo for 'foo' (assuming we already created it on github)
mkdir foo
pushd foo
git init
git remote add origin git@github.com:my-user/new-project.git
git pull ../ foo-only
git push origin -u master
popd

# Add 'foo' as a git submodule to `my-project`
git submodule add git@github.com:my-user/new-project.git foo

বিস্তারিত ডকুমেন্টেশনের জন্য (ম্যান পেজ), দয়া করে পড়ুন git-subtree.txt


10
গিট সাবট্রি শিলা!
সাইমন উডসাইড

3
কিন্তু সাবমডিউল ব্যবহার এড়াতে গিট-সাবট্রির বিন্দু নয়? আমি বলতে চাইছি আপনি প্রকৃতপক্ষে গিট-সাবট্রির লেখক (যদি কোনও ডাকনামের সংঘর্ষ না হয়) তবে এটি দেখতে গিট-সাবট্রি পরিবর্তিত বলে মনে হচ্ছে, যদিও আপনি প্রদর্শিত আদেশটি এখনও বৈধ বলে মনে হচ্ছে। আমি কি এই অধিকার পাচ্ছি?
ব্লেজারব্ল্যাড

17
1.7.11 হিসাবে গিট-সাবট্রি এখন গিটের অংশ (যদি আপনি অবদান ইনস্টল করেন)
জেরেমি

8
ভাল থেকে git rm -rf ./fooমুছে ফেলা fooহয় HEADতবে my-projectপুরো ইতিহাস ফিল্টার করে না । তারপরে, git submodule add git@github.com:my-user/new-project.git fooকেবলমাত্র fooএকটি সাবমডিউল থেকে শুরু করে HEAD। সেই ক্ষেত্রে, স্ক্রিপ্টিং filter-branchউচ্চতর হিসাবে এটি অর্জন করার অনুমতি দেয় "এমনভাবে করুন যেন সাবডির প্রথম থেকেই সাবমডিউল ছিল"
গ্রেগরি পাকোস্জ


38

চেকআউট গিট ফিল্টার-শাখা

Examplesঅধ্যায় যখন এটি ইতিহাসের সব এবং পালন অন্যান্য ফাইল / ডিরেক্টরি (শুধুমাত্র আপনার জন্য খুঁজছেন তা) ইতিহাস খারিজ কিভাবে এটা নিজস্ব প্রকল্পে একটি উপ-ডিরেক্টরির বের করে আনতে man পৃষ্ঠা শো।

ভান্ডারটিকে পুনরায় লেখার জন্য দেখতে যেমন foodir/এটির প্রকল্পের মূলটি ছিল এবং অন্য সমস্ত ইতিহাস বাতিল করে দিন:

   git filter-branch --subdirectory-filter foodir -- --all

সুতরাং আপনি উদাহরণস্বরূপ, একটি লাইব্রেরির সাব-ডাইরেক্টরিটিকে তার নিজস্ব ভাণ্ডারে পরিণত করতে পারেন। যেটি বিকল্পগুলি পুনর্বিবেচনার বিকল্পগুলি থেকে আলাদা করে এবং সমস্ত শাখা এবং ট্যাগগুলি পুনরায় লেখার জন্য
নোট করুন ।--filter-branch--all


1
এটি আমার পক্ষে ভাল কাজ করেছে। কেবলমাত্র খারাপ দিক আমি লক্ষ্য করেছি যে ফলাফলটি ছিল সমস্ত কমিট সহ একক মাস্টার শাখা।
aceofspades

@ স্পেসস্প্যাডস: কেন এটি একটি খারাপ দিক?
nnot101

2
আমার কাছে গিট রেপো থেকে কমিটস্ট এক্সট্রাক্ট করার পুরো বিষয়টি হ'ল আমি ইতিহাসটি ধরে রাখতে চাই।
aceofspades

13

এটি করার একটি উপায় হ'ল বিপরীতমুখী - আপনি যে ফাইলটি রাখতে চান সেই ফাইলটি বাদ দিয়ে সবকিছু সরিয়ে দিন।

মূলত, সংগ্রহস্থলের একটি অনুলিপি তৈরি করুন, তারপরে git filter-branchআপনি যে ফাইল / ফোল্ডার রাখতে চান তা বাদ দিয়ে সমস্ত কিছু সরিয়ে ফেলুন।

উদাহরণস্বরূপ, আমার একটি প্রকল্প রয়েছে যা থেকে আমি ফাইলটি tvnamer.pyএকটি নতুন সংগ্রহস্থলে বের করতে চাই :

git filter-branch --tree-filter 'for f in *; do if [ $f != "tvnamer.py" ]; then rm -rf $f; fi; done' HEAD

এটি git filter-branch --tree-filterপ্রতিটি প্রতিশ্রুতিবদ্ধ হওয়া, কমান্ড চালানো এবং ফলাফলের ডিরেক্টরি সামগ্রী পুনরায় স্বীকার করতে ব্যবহার করে। এটি অত্যন্ত ধ্বংসাত্মক (যাতে আপনার ভাণ্ডারের অনুলিপিটিতে কেবল এটি করা উচিত!) এবং কিছুক্ষণ সময় নিতে পারে (300 টি কমিট এবং প্রায় 20 টি ফাইল সহ একটি সংগ্রহস্থলের প্রায় 1 মিনিট)

উপরের কমান্ডটি প্রতিটি সংশোধনীর জন্য নিম্নলিখিত শেল-স্ক্রিপ্টটি চালিত করে, যা আপনাকে অবশ্যই সংশোধন করতে হবে (এটির পরিবর্তে এটি আপনার সাব ডিরেক্টরিটি বাদ দিতে tvnamer.py):

for f in *; do
    if [ $f != "tvnamer.py" ]; then
        rm -rf $f;
    fi;
done

সবচেয়ে বড় স্পষ্ট সমস্যা হ'ল এটি সমস্ত প্রতিশ্রুতিবদ্ধ বার্তাগুলি ছেড়ে দেয়, যদিও তারা বাকী ফাইলের সাথে সম্পর্কিত না হয়। স্ক্রিপ্ট গিট-রিমুভ-খালি-কমিট করে , এটি ঠিক করে দেয় ..

git filter-branch --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "$@"; else git commit-tree "$@"; fi'

আপনাকে যে কোনও কিছু দিয়ে আবার -fবল প্রয়োগ করতে হবে (মূলত এটি একটি ব্যাকআপ)filter-branchrefs/original/

অবশ্যই এটি কখনই নিখুঁত হতে পারে না, উদাহরণস্বরূপ, যদি আপনার প্রতিশ্রুতিবদ্ধ বার্তাগুলি অন্য ফাইলগুলি উল্লেখ করে তবে এটি প্রায় একটি গিট কারেন্টের অনুমতি দেয় (যতদূর আমি সচেতন থাকি))

আবার, কেবল আপনার সংগ্রহশালার অনুলিপিটিতে এটি চালান! - তবে সংক্ষেপে, সমস্ত ফাইল অপসারণ করতে "thisismyfilename.txt":

git filter-branch --tree-filter 'for f in *; do if [ $f != "thisismyfilename.txt" ]; then rm -rf $f; fi; done' HEAD
git filter-branch -f --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "$@"; else git commit-tree "$@"; fi'

4
git filter-branch(আজকাল?) খালি কমিটগুলি অপসারণের একটি অন্তর্নির্মিত বিকল্প রয়েছে, যথা --prune-empty। থেকে উত্তম পথপ্রদর্শক git filter-branchএই প্রশ্নের উত্তর রয়েছে: stackoverflow.com/questions/359424/...
Blaisorblade

4

CoolAJ86 এবং apenwarr উভয় উত্তর খুব মিল। আমি দু'জনের মাঝে পিছনে গিয়ে বিটগুলি বুঝতে চেষ্টা করলাম যা দুটির মধ্যে একটিরও অনুপস্থিত ছিল। নীচে তাদের একটি সংমিশ্রণ দেওয়া আছে।

বিভক্ত হওয়ার জন্য প্রথমে গিট বাশকে গিট রেপুরের মূলে নেভিগেট করুন। আমার উদাহরণে এটি এখানে~/Documents/OriginalRepo (master)

# move the folder at prefix to a new branch
git subtree split --prefix=SubFolderName/FolderToBeNewRepo --branch=to-be-new-repo

# create a new repository out of the newly made branch
mkdir ~/Documents/NewRepo
pushd ~/Documents/NewRepo
git init
git pull ~/Documents/OriginalRepo to-be-new-repo

# upload the new repository to a place that should be referenced for submodules
git remote add origin git@github.com:myUsername/newRepo.git
git push -u origin master
popd

# replace the folder with a submodule
git rm -rf ./SubFolderName/FolderToBeNewRepo
git submodule add git@github.com:myUsername/newRepo.git SubFolderName/FolderToBeNewRepo
git branch --delete --force to-be-new-repo

নীচে কাস্টমাইজ-সক্ষম নামগুলি প্রতিস্থাপন এবং পরিবর্তে https ব্যবহার করে উপরে একটি অনুলিপি দেওয়া আছে। রুট ফোল্ডার এখন~/Documents/_Shawn/UnityProjects/SoProject (master)

# move the folder at prefix to a new branch
git subtree split --prefix=Assets/SoArchitecture --branch=so-package

# create a new repository out of the newly made branch
mkdir ~/Documents/_Shawn/UnityProjects/SoArchitecture
pushd ~/Documents/_Shawn/UnityProjects/SoArchitecture
git init
git pull ~/Documents/_Shawn/UnityProjects/SoProject so-package

# upload the new repository to a place that should be referenced for submodules
git remote add origin https://github.com/Feddas/SoArchitecture.git
git push -u origin master
popd

# replace the folder with a submodule
git rm -rf ./Assets/SoArchitecture
git submodule add https://github.com/Feddas/SoArchitecture.git
git branch --delete --force so-package

3

যদি আপনি কোনও ফাইলের কিছু উপসেট একটি নতুন ভান্ডারে স্থানান্তর করতে চান তবে ইতিহাস রাখতে চান তবে আপনি মূলত সম্পূর্ণ নতুন ইতিহাসের সাথে শেষ করতে চলেছেন। এটি যেভাবে কাজ করবে তা মূলত:

  1. নতুন সংগ্রহস্থল তৈরি করুন।
  2. আপনার পুরাতন সংগ্রহস্থলের প্রতিটি সংশোধনের জন্য, আপনার মডিউলে পরিবর্তনগুলি নতুন ভাণ্ডারে রূপান্তর করুন। এটি আপনার বিদ্যমান প্রকল্পের ইতিহাসের একটি "অনুলিপি" তৈরি করবে।

আপনি যদি একটি ছোট তবে লোমশ স্ক্রিপ্ট লেখার বিষয়ে আপত্তি না দেখান তবে এটি স্বয়ংক্রিয়ভাবে কিছুটা সোজা হওয়া উচিত। সোজা, হ্যাঁ, তবে বেদনাদায়কও। লোকেরা অতীতে গিটে ইতিহাসের পুনর্লিখন করেছিল, আপনি এটির জন্য অনুসন্ধান করতে পারেন।

বিকল্পভাবে: সংগ্রহস্থলটিকে ক্লোন করুন এবং ক্লোনটির কাগজ মুছুন, অ্যাপ্লিকেশনটিকে মূলতে মুছুন। এটি এক মিনিট সময় নেয়, এটি কাজ করার গ্যারান্টিযুক্ত এবং আপনি আপনার গিট ইতিহাসকে বিশুদ্ধ করার চেষ্টা করার চেয়ে আরও গুরুত্বপূর্ণ জিনিসগুলিতে ফিরে আসতে পারেন। এবং ইতিহাসের অনর্থক অনুলিপি দ্বারা নেওয়া হার্ড ড্রাইভের জায়গা সম্পর্কে চিন্তা করবেন না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.