Як я можу виправити підребро git після того, як сила проекту, що надходить на потік, натиснута на master?


13

Я експериментував з використанням git subtree і зіткнувся з наступною ситуацією.

Я використовував піддерево git, щоб додати зовнішній проект до мого репо, я навмисно зберігав всю історію для висхідного проекту, оскільки я хочу мати можливість посилатися на історію проекту, а також пізніше внести свій внесок у проект вище.

Як виявилося, інший учасник проекту вгору за течією випадково засунув великий файл у головну гілку. Щоб виправити це, проект вище за течією переписав історію і силою натиснув на головного. Створюючи своє "монорепо", я включив цю команду, і я також хотів би її зняти.

Як я можу оновити своє сховище, щоб відобразити нову історію піддірева?

Моєю першою спробою було використовувати фільтр-гілку, щоб повністю видалити піддірець і всю історію.

git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch upstream-project-dir' --prune-empty HEAD

Після того, як стару версію піддерева було видалено, я можу повторно додати підкресливе дерево, використовуючи новий головний майстер висхідного потоку. Однак це не спрацювало, оскільки чомусь історія фіксування все ще відображається у виведенні журналу git.

Оновлення

Я написав кроки для створення мінімально відтворюваного прикладу.

  1. Спочатку створіть порожнє git repo.

    git init test-monorepo
    cd ./test-monorepo
    
  2. Створіть початковий комікс.

    echo hello world > README
    git add README
    git commit -m 'initial commit'
    
  3. Тепер додайте піддерево для зовнішнього проекту.

    git remote add thirdparty git@github.com:teivah/algodeck.git
    git fetch thirdparty
    git subtree add --prefix algodeck thirdparty master
    
  4. Зробіть кілька зобов’язань на монорепо

    echo dont panic >> algodeck/README.md
    git commit -a -m 'test commit'
    
  5. Тепер спробуйте використати фільтр-гіт git для видалення піддіаграму.

    git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch algodeck' --prune-empty HEAD
    
  6. Вивчіть вихід журналу git, я очікую побачити лише моє початкове введення.

    git log
    

Ви спробували git gc --prune = зараз, щоб викинути старі коміти? Чи є деякі посилання на стару версію?
Даміано

1
Я ще цього не пробував, але чи не git gc --prune=nowвидаляв би лише документи, які не відображаються в git log?
csnate

використання git гілки -all (що, я думаю, ви використовуєте для перегляду "старих" комітетів), повинно також показувати комітети, не пов'язані з вашою поточною гілкою.
Даміано

1
Насправді я просто робив git log, ніяких аргументів, і я все ще бачу старі коміти.
csnate

Чи можете ви опублікувати свій журнал git --pretty --all --graph? Просто, щоб зрозуміти вашу ситуацію
Даміано

Відповіді:


0

ви вже отримали погане вчинення в своїй історії, і вам потрібно позбутися від нього, перш ніж продовжувати

припустимо, ви masterпереадресували останнє зобов’язання і не змогли зробити нічого іншого (я справді не маю ваших гілок на увазі, тому мені потрібно припустити щось із початку)

ви можете повернутись до попереднього комітету і відсунути маркер відділення на 1 крок назад (або X кроки назад), що в будь-якому випадку було б нешкідливим, а потім знову потягніть

напр

git checkout master~1
git branch master -f
git checkout master
git pull
  1. git checkout master~1 щоб перевірити батьківські зобов’язання господаря, git попереджає, що ми не з гілок
  2. git branch master -f щоб змусити поточну реєстрацію знову стати майстром, тобто вона фактично перемотає головну гілку на свою попередню фіксацію (або X попередню фіксацію), і звідси не має значення, чи зробили силу чи ні, ми можемо відновити нормально або навіть Поверніться до вищевказаного кроку, якщо це потрібно, ми можемо лише знову підтягнути майстра, не втрачаючи нічого із висхідного потоку (що також для нас може бути лише для читання; ми нічого для цього не натискатимемо)
  3. git checkout master бути на нашому "перемотанному" головному відділенні, тому самому зобов'язанні, на яке ми крокуємо, але зараз на цьому
  4. git pullзнову витягнути майстра (можна з або без --prune), якщо вгору за течією буде відвернено, ми повернемося звідси, якщо ні, то отримаємо те саме, що у нас було, якщо ми отримали те саме і не передбачалося, можливо, ми потрібно повернутися до першого кроку вище та перемотати більше команд, наприклад, git checkout master~5будь-якого іншого (за потреби)

Я не думаю, що це спрацюєgit subtree
csnate

@csnate можна оформити попередні коммітов з subrepo і слідувати дуже схожу процедуру, якщо ви будуєте MCVE було б простіше сказати вам точні команди слідувати stackoverflow.com/help/minimal-reproducible-example
arhak

Я спробую створити зразок репо на GitHub.
csnate

Я створив набір кроків у вихідному питанні, яке показує проблему.
csnate

0
  1. на репо, очистіть історію комісій для цього віддаленого пристрою:

    git fetch upstream
    
  2. якщо в одному з ваших власних комісій є документ, який включає великий файл, перепишіть історію, щоб цей великий файл більше не посилався

    # using one or more of the following commands :
    git rebase --interactive
    git filter-branch
    ...
    

З допомогою цих двох кроків великий файл вже не посилатиметься жодним комітетом у вашій репо-репортажі.
Він також буде видалений з вашого жорсткого диска в якийсь момент часу, коли git запустить свій сміттєзбірник і буде досягнуто затримки терміну дії звисаючих крапель.


Якщо у вас є термінова необхідність видалити цей великий файл як можна швидше з вашого жорсткого диска:

Ручне керування

git gc --prune=now
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.