Я думаю, що ваша основна проблема тут полягає в тому, що ви неправильно трактуєте та / або нерозумієте, що робить git і чому це робить.
Коли ви клонуєте якесь інше сховище, git робить копію всього, що там "там". Він також приймає "їх" ярлики гілок, таких як master
, і робить копію тієї мітки, "повне ім'я" у вашому дереві git є (як правило) remotes/origin/master
(але у вашому випадку, remotes/upstream/master
). У більшості випадків ви також опускаєте remotes/
частину, тому ви можете посилатися на цю оригінальну копію як upstream/master
.
Якщо тепер внести і внести деякі зміни (файли) в який-небудь файл (и), ти єдиний із цими змінами. Тим часом інші люди можуть використовувати оригінальний сховище (з якого ви зробили свій клон), щоб зробити інші клони та змінити їх. Вони, звичайно, єдині зі своїми змінами. Зрештою, у когось можуть бути зміни, які вони надсилають назад первинному власнику (за допомогою "push", патчів чи будь-чого іншого).
git pull
Команда в основному тільки обраховувати для git fetch
подальшої git merge
. Це важливо, оскільки це означає, що вам потрібно зрозуміти, що насправді роблять ці дві операції.
git fetch
Команда каже , щоб повернутися туди , де ви клонували з (або в іншому випадку встановити в якості місця для вилучення з) і знайти «новий матеріал хто - то додали або змінені або видалені». Ці зміни копіюються та застосовуються до вашої копії того, що ви отримали від них раніше . Вони не застосовуються до вашої власної роботи, лише до їхньої роботи.
git merge
Команда складніша і де ви збираєтеся наперекосяк. Що це робиться, трохи спрощено, це порівняти "те, що ви змінили в своїй копії", "зміни, які ви отримали від когось іншого, і таким чином додали до вашої роботи" копія-чи-то-кого-небудь ". Якщо ваші зміни та їх зміни, здається, не суперечать, merge
операція з'єднує їх і дає вам "злиття", яке пов'язує ваш розвиток та їх розвиток разом (хоча є дуже поширений "легкий" випадок, у якому у вас немає змінюється, і ви отримуєте "швидкий вперед").
Ситуація Ви стикаєтеся зараз один , в якому були внесені зміни та скоїв їх дев'ять разів, справді, отже, «попереду 9» -І вони не зробили ні одного зміни. Отже, fetch
слухняно витягує нічого, а потім merge
приймає їх нестачу змін, а також нічого не робить.
Те, що ви хочете, - це подивитися, а може, навіть "скинути" на "їх" версію коду.
Якщо ви просто хочете подивитися, ви можете просто перевірити цю версію:
git checkout upstream/master
Це вказує git, що ви хочете перемістити поточний каталог у гілку, повна назва якої є насправді remotes/upstream/master
. Ви побачите їх код станом на останній раз, коли ви запустили git fetch
та отримали останній код.
Якщо ви хочете відмовитися від усіх власних змін, то вам потрібно змінити ідею git про те, що переглядати ваш ярлик,, master
слід назвати. В даний час він називає ваші найсвіжіші коміти. Якщо ви повернетесь до цієї гілки:
git checkout master
тоді git reset
команда дозволить вам "перемістити мітку", як би там не було. Єдина проблема, що залишилася (якщо припустити, що ви справді готові відмовитися від усього, що ви робите) - це пошук місця, куди повинна вказувати мітка.
git log
дозволить вам знайти числові імена - такі речі, як 7cfcb29
- які є постійними (ніколи не змінюються) іменами, і є безглузде число інших способів їх назви, але в цьому випадку ви просто хочете, щоб ім'я upstream/master
.
Щоб перемістити мітку, знищивши свої зміни (ті , які ви зробили фактично відшкодовано досить довгий час , але це набагато складніше після того, як це так бути дуже впевнений):
git reset --hard upstream/master
--hard
Розповідає мерзотник , щоб знищити те , що ви робите, перемістити поточну мітку гілки, а потім перевірити дане зобов'язання.
Це не надто звичайно, щоб дійсно захотіти git reset --hard
і знищити купу роботи. Більш безпечний метод (полегшити відновлення роботи, якщо ви вирішите, що все-таки варто було зрештою) - перейменувати існуючу галузь:
git branch -m master bunchofhacks
а потім складіть нову локальну гілку з назвою master
"треки" (мені не дуже подобається цей термін, оскільки я думаю, що він бентежить людей, але це термін git :-)) походження (або вище) майстер:
git branch -t master upstream/master
яку ви можете потім набути на себе:
git checkout master
Те, що роблять останні три команди (є ярлики, щоб зробити це лише двома командами), - це змінити ім'я, вставлене на існуючу мітку, а потім зробити нову мітку, а потім перейти до неї:
перш ніж робити що-небудь:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "master"
після git branch -m
:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
після git branch -t master upstream/master
:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
Ось C0
остання фіксація (повне дерево джерела), яку ви отримали, коли ви вперше зробили своє git clone
. Від C1 до C9 - це ваші зобов'язання.
Зауважте, що якби ви git checkout bunchofhacks
і тоді git reset --hard HEAD^^
, це змінило б останню картину на:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 - "bunchofhacks"
\
\- C8 --- C9
Причина полягає в тому, що називається HEAD^^
редакція дві вгору від голови поточної гілки (що безпосередньо до скидання буде bunchofhacks
), а reset --hard
потім переміщує мітку. Коміти C8 і C9 в основному невидимі (ви можете використовувати такі речі, як рефлог, і git fsck
знаходити їх, але це вже не банально). Ваші етикетки ваші, щоб рухатись, як завгодно. fetch
Команда піклується про тих , які починаються з remotes/
. Це звичайне співставлення "ваше" з "їхнім" (тому, якщо вони мають remotes/origin/mauve
назву і вашого mauve
), але ви можете вводити "їх", коли ви хочете назвати / побачити комісії, які ви отримали "від них". (Пам'ятайте, що "одна фіксація" - це ціле дерево джерела. Ви можете вибрати один конкретний файл з одного коміту, git show
наприклад,