Kā es varu saskaņot atdalīto HEAD ar master/origin?

Es esmu jauns Git sazarošanās sarežģītības. Es vienmēr strādāju vienā atzarā un veicu izmaiņas, un tad periodiski veicu push uz manu attālo izcelsmi.

Nesen es kaut kur atiestatīju dažus failus, lai izņemtu tos no commit staging, un vēlāk veicu rebase -i, lai atbrīvotos no pāris nesen izdarītiem vietējiem grozījumiem. Tagad es esmu nonācis tādā stāvoklī, kuru īsti nesaprotu.

Manā darba zonā git log rāda tieši to, ko es gaidīju - es esmu pareizajā vilcienā ar tiem nodevumiem, kurus es negribēju, un jaunajiem utt.

Bet es tikko uzstājos uz attālināto repozitāriju, un tas, kas tur ir, ir atšķirīgs - pāris no manis nogalinātajiem commitiem rebase tika uzstumti, un jauno, lokāli izdarīto, tur nav.

Es domāju, ka "master/origin" ir atdalīts no HEAD, bet man nav 100% skaidrs, ko tas nozīmē, kā to vizualizēt ar komandrindas rīkiem un kā to novērst.

Risinājums

Vispirms noskaidrosim, kas ir HEAD un ko nozīmē, ja tas ir atdalīts.

HEAD ir pašlaik pārbaudītās kopijas simboliskais nosaukums. Ja HEAD nav atdalīts ("normālā" 1 situācija: ir pārbaudīts atzars), HEAD faktiski norāda uz zara "ref", un atzars norāda uz nodošanu. Tādējādi HEAD ir "pievienots" atzaram. Veicot jaunu nodošanu, atzars, uz kuru norāda HEAD, tiek atjaunināts, lai norādītu uz jauno nodošanu. HEAD seko automātiski, jo tas vienkārši norāda uz zaru.

  • git symbolic-ref HEAD dod refs/heads/master. Tiek pārbaudīts atzars ar nosaukumu "master".
  • git rev-parse refs/heads/master yield 17a02998078923f2d62811326d130de991d1a95a Šis nodevums ir galvenā atzara pašreizējais gals jeb "galva".
  • git rev-parse HEAD arī dod 17a0299998078923f2d62811326d130de991d1a95a. Tas ir tas, ko nozīmē būt "simboliskai atsaucei". Tas norāda uz objektu, izmantojot kādu citu atsauci.
    (Simboliskās atsauces sākotnēji tika ieviestas kā simboliskās saites, bet vēlāk tās tika pārveidotas par parastiem failiem ar papildu interpretāciju, lai tās varētu izmantot platformās, kurās nav simbolu saišu.)

Mums ir HEADrefs/heads/master17a0299998078923f2d62811326d130de991d1a95a

Kad HEAD ir atdalīts, tas norāda tieši uz nodevumu, nevis netieši, izmantojot zaru. Var domāt, ka atdalītais HEAD ir uz nenoteikta zara.

  • git symbolic-ref HEAD neizdodas ar fatal: ref HEAD nav simboliska atsauce.
  • git rev-parse HEAD dod 17a0299998078923f2d62811326d130de991d1a95a. Tā kā tas nav simbolisks ref, tam ir jānorāda tieši uz pašu nodošanu.

Mums ir HEAD17a02998078923f2d62811326d130de991d1a95a.

Svarīgākais, kas jāatceras, lietojot atdalīto HEAD, ir tas, ka, ja sesija, uz kuru tas norāda, ir citādi neatsaucama (uz to neattiecas neviena cita atsauce), tad, pārbaudot kādu citu sesiju, tā kļūs "karājas". Galu galā šādas "karājas" atdalītās izmaiņas tiks izcirstas atkritumu savākšanas procesā (pēc noklusējuma tās tiek saglabātas vismaz 2 nedēļas, bet, ja uz tām atsaucas HEAD reflogs, tās var tikt saglabātas ilgāk).

1 Pilnīgi normāli strādāt ar atdalītu HEAD, tikai ir jāseko līdzi tam, ko darāt, lai izvairītos no tā, ka no refloga ir jāizlasa izmetumu vēsture.


Interaktīvās atjaunošanas starpposmus veic ar atdalītu HEAD (daļēji, lai izvairītos no aktīvā zara refloga piesārņošanas). Ja pabeigsiet pilnu pārbāzes operāciju, tā atjauninās jūsu sākotnējo zaru ar pārbāzes operācijas kumulatīvo rezultātu un no jauna pievienos HEAD sākotnējam zaram. Domāju, ka jūs nekad neesat pilnībā pabeidzis pārbase procesu; tādējādi jums paliks atdalīts HEAD, kas norādīs uz pēdējo pārbase operācijā apstrādāto revīziju.

Lai atgūtos no jūsu situācijas, jums jāizveido zars, kas norāda uz nodošanu, uz kuru pašlaik norāda jūsu atdalītā HEAD:

git branch temp
git checkout temp

(šīs divas komandas var saīsināti saukt git checkout -b temp)

Tas atkārtoti pievienos jūsu HEAD jaunajam atzaram temp.

Pēc tam jums jāsalīdzina pašreizējā nodošana (un tās vēsture) ar parasto zaru, kurā jūs plānojat strādāt:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(Iespējams, vēlēsieties eksperimentēt ar žurnāla opcijām: pievienojiet -p, atmetiet --pretty=..., lai redzētu visu žurnāla ziņojumu utt.).

Ja jūsu jaunais temp atzars izskatās labi, jūs varat atjaunināt (piemēram,) master, lai norādītu uz to:

git branch -f master temp
git checkout master

(šīs divas komandas var saīsināt kā git checkout -B master temp)

Pēc tam varat izdzēst pagaidu zaru:

git branch -d temp

Visbeidzot, jūs, iespējams, vēlēsieties virzīt atjaunoto vēsturi:

git push origin master

Iespējams, ka šīs komandas beigās būs nepieciešams pievienot --force, lai push veiktu, ja attālināto atzaru nav iespējams "ātri pārvirzīt" uz jauno nodošanu (t. i., jūs esat atmetis vai pārrakstījis kādu jau esošo nodošanu, vai kā citādi pārrakstījis kādu vēstures daļu).

Ja jūs bijāt pa vidu pārbāzes operācijai, jums, iespējams, vajadzētu to sakopt. Varat pārbaudīt, vai ir notikusi atkārtota izlīdzināšana, meklējot direktoriju .git/rebase-merge/. Jūs varat manuāli iztīrīt notiekošo rebase, vienkārši dzēšot šo direktoriju (piemēram, ja vairs neatceraties aktīvās rebase operācijas mērķi un kontekstu). Parasti jāizmanto git rebase --abort, bet tas veic papildu atiestatīšanu, no kuras, iespējams, vēlaties izvairīties (tas pārvieto HEAD atpakaļ uz sākotnējo zaru un atiestata to atpakaļ uz sākotnējo nodošanu, tādējādi atceļot daļu iepriekš paveiktā darba).

Komentāri (22)

Atdalītās galvas pamatskaidrojumu skatiet šeit:

http://git-scm.com/docs/git-checkout.

Komandas rinda, lai to vizualizētu:

git branch

vai

git branch -a

jūs saņemsiet šādu izvades rezultātu:

* (no branch)
master
branch1

* (nav filiāles) rāda, ka esat atdalītā galvā.

Jūs varējāt nonākt šādā stāvoklī, veicot git checkout somecommit u.c., un tas jūs būtu brīdinājis šādi:

Jūs atrodaties 'atdalītās GALVAS' stāvoklī. Jūs varat apskatīties apkārt, veikt eksperimentālus darbus. izmaiņas un izdarīt tās, un jūs varat atteikties no jebkuras apņemšanās, ko veicat šajā laikā. stāvoklī, neietekmējot nevienu zaru veicot citu pārbaudi.

Ja vēlaties izveidot jaunu atzaru, lai saglabāt izveidotās nodevumus, varat to izdarīt. to darīt (tagad vai vēlāk), izmantojot -b ar komandu checkout komandu vēlreiz. Piemērs:

git checkout -b new_branch_name

Tagad, lai tos pārnestu uz master:

Veiciet git reflog vai pat tikai git log un atzīmējiet savas izmaiņas. Tagad git checkout master un git merge.

git merge HEAD@{1}

Rediģēt:

Lai pievienotu, izmantojiet git rebase -i ne tikai dzēšot / nogalinot jums nevajadzīgus nodevumus, bet arī rediģējot tos. Vienkārši norādiet "rediģēt" kopiju sarakstā, un jūs varēsiet grozīt savu kopiju un pēc tam izdot git rebase --continue, lai turpinātu darbu. Tas nodrošinātu, ka jūs nekad nenonāktu atdalītā HEAD.

Komentāri (2)

Saņemiet savu atdalīto nodevumu savā filiālē

Vienkārši palaidiet git checkout -b mynewbranch.

Pēc tam palaidiet git log, un jūs redzēsiet, ka šī nodošana tagad ir HEAD šajā jaunajā atzarā.

Komentāri (2)