Примушуйте "git push" перезаписати віддалені файли


766

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

Як я можу це зробити з Git?


106
Не git push origin --forceпрацювали для вас?


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

@Mike, яка працює для мене чомусь ... цікаво, що було з ОП

Ймовірна причина, що натискання на силу не працює, це те, що вона могла бути явно відключена на віддаленому репо (щоб забезпечити нічого не втрачає через ідіотичних та / або злісних дописувачів): використовуйте config receive.denyNonFastforwardsдля з'ясування.
Френк Нокк

Відповіді:


1085

Ви повинні мати можливість примусити місцеве перегляду на віддалене репо, використовуючи

git push -f <remote> <branch>

(наприклад git push -f origin master). Відпустившись <remote>і <branch>змусить натиснути всі локальні гілки, які встановили --set-upstream.

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

Оновлення : Думав, я б додав бічну ноту. Якщо ви створюєте зміни, які переглядатимуть інші, то не рідкість створювати гілку з цими змінами та періодично проводити перезавантаження, щоб вони були в курсі основної галузі розвитку. Дозвольте іншим розробникам знати, що це буде періодично, щоб вони знали, чого очікувати.

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

Скажіть, я клонував ваше репо і додав декілька так:

            D ---- E тема
           /
A ---- B ---- C розвиток

Але пізніше developmentгілка буде натиснута на rebase, що призведе до того, що я отримаю помилку, наприклад, коли я запускаю git pull:

Розпакування предметів: 100% (3/3), зроблено.
З <переположення>
 * розвиток галузі -> FETCH_HEAD
Автоматичне об’єднання <файлів>
КОНФЛІКТ (зміст): конфлікт об'єднання в <місцях>
Помилка автоматичного злиття; виправити конфлікти, а потім здійснити результат.

Тут я міг би виправити конфлікти і commit, але це залишило б мені справді некрасиву історію вчинення:

       C ---- D ---- E ---- F тема
      //
A ---- B -------------- C 'розвиток

Використовувати це може здатися привабливим, git pull --forceале будьте обережні, тому що це залишить вас з натягнутими зобов'язаннями:

            D ---- E тема

A ---- B ---- C 'розвиток

Тому, мабуть, найкращий варіант - це зробити git pull --rebase. Це вимагає від мене вирішення будь-яких конфліктів, як раніше, але я буду використовувати кожен крок замість того, щоб вчиняти git rebase --continue. Врешті-решт історія комісій буде виглядати набагато краще:

            D '--- E' тема
           /
A ---- B ---- C 'розвиток

Оновлення 3: Ви також можете використовувати цю --force-with-leaseопцію як "безпечніший" силовий поштовх, як згадував Cupcake у своїй відповіді :

Силове натискання з "орендою" дозволяє примусовому натисканню вийти з ладу, якщо на пульті дистанційного керування з’являються нові коміти (технічно, якщо ви ще не взяли їх у відділення віддаленого відстеження), що корисно, ви не хочете випадково перезаписати чужі зобов’язання, про які ви ще навіть не знали, і просто хочете перезаписати свої власні:

git push <remote> <branch> --force-with-lease

Ви можете дізнатися більше подробиць про використання --force-with-lease, прочитавши будь-яке з наступного:


5
Оскільки це обрана відповідь, я прокоментую тут. Використання сили не є проблемою, коли ви працюєте самостійно. Наприклад, мій хмарний хост починається з власного git. Якщо я працюю локально і будую проект, і хочу розмістити його на своєму хмарному хості (OpenShift), у мене є два окремих git-проекти. Мій локальний і мій OpenShift. Я отримую свій локальний так само, як мені подобається, але тепер хочу переглянути його на моєму OpenShift. Потім ви вперше натискаєте на OpenShift, використовуючи -fпрапор. По суті, покладіть свій локальний git на OpenShift.
Вейд

128

Ви хочете натиснути

Що ви в основному хочете зробити, це змусити натиснути локальну гілку, щоб замінити віддалену.

Якщо ви хочете більш детально пояснити кожну з наступних команд, то дивіться розділ мої деталі нижче. У вас в основному є 4 різні варіанти силового натискання за допомогою Git:

git push <remote> <branch> -f
git push origin master -f # Example

git push <remote> -f
git push origin -f # Example

git push -f

git push <remote> <branch> --force-with-lease

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

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

Примушуйте розсовувати деталі

Вказівка ​​віддаленого та відділення

Ви можете повністю вказати конкретні гілки та віддалений. -fПрапор коротка версія--force

git push <remote> <branch> --force
git push <remote> <branch> -f

Опущення гілки

Коли гілка для виведення гілки опущена, Git визначить це на основі налаштувань конфігурації. У версіях Git після 2.0, нове репо матиме налаштування за замовчуванням, щоб натиснути гілку, яку ви перевірили:

git push <remote> --force

в той час, як до 2.0, нові репости матимуть налаштування за замовчуванням для просування декількох локальних відділень. Ці параметри є remote.<remote>.pushта push.defaultналаштуваннями (див. Нижче).

Опускаючи пульт та гілку

Коли і пульт, і гілка опущені, поведінка справедливості git push --forceвизначається вашими push.defaultналаштуваннями Git config:

git push --force
  • Станом на Git 2.0, налаштування за замовчуванням simple, в основному, просто підштовхне поточну гілку до її віддаленої віддаленої частини. Пульт дистанційного керування визначається налаштуваннями гілки branch.<remote>.remote, а за замовчуванням походить початкове репо в іншому випадку.

  • Перед Git версією 2.0, налаштування за замовчуванням matching, як правило, просто виштовхує всі ваші локальні гілки до гілок з тим самим іменем на пульті дистанційного керування (що за замовчуванням походить).

Ви можете прочитати додаткові push.defaultпараметри, прочитавши git help configабо в Інтернеті версію git-config (1) Сторінка посібника .

Примушуйте безпечніше натискати --force-with-lease

Силове натискання з "орендою" дозволяє примусовому натисканню вийти з ладу, якщо на пульті дистанційного керування з’являються нові коміти (технічно, якщо ви ще не взяли їх у відділення віддаленого відстеження), що корисно, ви не хочете випадково перезаписати чужі зобов’язання, про які ви ще навіть не знали, і просто хочете перезаписати свої власні:

git push <remote> <branch> --force-with-lease

Ви можете дізнатися більше подробиць про використання --force-with-lease, прочитавши будь-яке з наступного:


Ви маєте рацію, але це дійсно слід використовувати лише у виняткових ситуаціях.
Скотт Берревойц

1
@ScottBerrevoets " Я вважаю за краще, щоб натиснути на те, що у мене є, і нехай це перезаписувати віддалено, а не інтегрувати ". Я дав ОП саме те, що він просив.

Я знаю, але ОП може не знати про наслідки цього. Ви технічно відповіли на питання, але я вважаю, що попередження не робити цього не є правильним.
Scott Berrevoets

1
@ScottBerrevoets Я намагаюся модератора об'єднати свою відповідь у канонічну, тому що я згадую про новий --force-with-leaseваріант;)


32

Інший варіант (щоб уникнути будь-якого вимушеного натиску, який може бути проблематичним для інших учасників), це:

  • розмістіть свої нові зобов’язання у спеціалізованій галузі
  • скидання masterONorigin/master
  • об’єднайте свою виділену гілку master, завжди зберігаючи комісії від спеціалізованої гілки (тобто створюйте нові зміни, над masterякими відображатиметься ваша спеціалізована гілка).
    Дивіться " Команда git для створення однієї гілки як іншої " щодо стратегій для імітації git merge --strategy=theirs.

Таким чином, ви можете підштовхнути майстра до віддаленого, нічого не змушуючи примушувати.


Чим результат відрізняється від "push -force"?
alexkovelsky

6
@alexkovelsky Будь-який примусовий поштовх переписує історію, змушуючи інших користувачів репо скинути власне місцеве репо, щоб вони відповідали нещодавно переданим комітетам. Такий підхід створює лише нові зобов'язання і не вимагає примусового поштовху.
VonC

1
Я пропоную вам додати заголовок до своєї відповіді: "Ви не хочете змушувати натискати" :)
alexkovelsky

@alexkovelsky Добрий момент. Відповідь я відредагував відповідно.
VonC

4

git push -f трохи руйнівний, оскільки він скидає будь-які віддалені зміни, які були внесені будь-ким у команді. Більш безпечним варіантом є {git push --force-with-lease}.

Що {--force-with-lease} робить, це відмовитись від оновлення філії, якщо не очікується такий стан; тобто ніхто не оновлював гілку вище за течією. На практиці це працює, перевіряючи, чи є те, що ми очікуємо, що реф. По течії є те, що ми вважаємо хешами, і неявно кодує ланцюжок батьків у їхню цінність. Ви можете сказати {--force-with-lease}, що саме потрібно перевірити, але за замовчуванням буде перевіряти поточний віддалений номер. Це означає на практиці, що коли Аліса оновлює свою гілку та підштовхне її до віддаленого сховища, голова філії, що вказує, буде оновлена. Тепер, якщо Боб не витягне з пульта, його місцеве посилання на пульт буде застарілим. Коли він перейде до натискання, використовуючи {--force-with-lease}, git перевірить місцевий відмову від нового дистанційного та відмовиться змусити натиснути. {--force-with-lease} ефективно дозволяє лише примусово натискати, якщо ніхто не проміняв зміни до віддаленого проміжку часу. Це {--force} з надітним ременем безпеки.



0

Прості кроки за допомогою tortoisegit

GIT надає локальні файли фіксації та переміщення у сховище git.

Кроки:

1) приховування змін імені сховища

2) тягнути

3) прихований поп

4) ввести 1 або більше файлів і дати опис змін зміни, встановлений автором та датою

5) поштовх

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