Hoe krijg ik slechts één bestand van een andere branch?

Ik gebruik Git en werk aan de masterbranch. Deze tak heeft een bestand met de naam app.js.

Ik heb een experimentbranch waarin ik een heleboel veranderingen en tonnen commits heb gemaakt. Nu wil ik alle aangebrachte wijzigingen alleen in app.jsbrengen van experimentnaar masterbranch.

Hoe doe ik dat?

Nogmaals, ik wil geen samenvoeging. Ik wil gewoon alle wijzigingen in app.jsvan de vertakking experimentnaar de vertakking masterbrengen.


Antwoord 1, autoriteit 100%

git checkout master               # first get back to master
git checkout experiment -- app.js # then copy the version of app.js 
                                  # from branch "experiment"

Zie ook git hoe wijzigingen van één bestand ongedaan te maken?


Update augustus 2019, Git 2.23

Met de nieuwe git switchen git restorecommando’s, dat zou zijn:

git switch master
git restore --source experiment -- app.js

Standaard wordt alleen de werkboom hersteld.
Als u ook de index wilt bijwerken (wat betekent dat u de bestandsinhoud wilt herstellen, endeze in één opdracht aan de index wilt toevoegen):

git restore --source experiment --staged --worktree -- app.js
# shorter:
git restore -s experiment -SW -- app.js

Zoals Jakub Narebskivermeldt in de opmerkingen:

git show experiment:path/to/app.js > path/to/app.js

werkt ook, behalve dat, zoals beschreven in de SO-vraag “Hoe haal je een enkel bestand op uit een specifieke revisie in Git?“, moet je het volledige pad van de hoofdmap van de repo gebruiken.
Vandaar het pad/naar/app.js dat Jakub in zijn voorbeeld gebruikte.

Zoals Frostyvermeldt in de opmerking:

u krijgt alleen de meest recente status van app.js

Maar voor git checkoutof git show, kun je naar elke gewenste revisie verwijzen, zoals geïllustreerd in de SO-vraag “git checkout-revisie van een bestand in git gui“:

$ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME

zou hetzelfde zijn als $FILENAME een volledig padis van een bestand met versiebeheer.

$REVISIONkan zijn zoals getoond in git rev-parse:

experiment@{yesterday}:app.js # app.js as it was yesterday 
experiment^:app.js            # app.js on the first commit parent
experiment@{2}:app.js         # app.js two commits ago

en ga zo maar door.

schmijosvoegt in de reacties:

je kunt dit ook doen vanuit een voorraad:

git checkout stash -- app.js

Dit is erg handig als je aan twee branches werkt en je je niet wilt binden.


Antwoord 2, autoriteit 23%

Alles is veel eenvoudiger, gebruik daarvoor git checkout.

Stel dat you're on masterbranch zit, om app.js from new-featurebranch te krijgen :

git checkout new-feature path/to/app.js
// note that there is no leading slash in the path!

Hiermee krijgt u de inhoud van het gewenste bestand. Je kunt, zoals altijd, een deel van sha1 gebruiken in plaats vannieuwe functietaknaamom het bestand als het was in die specifieke commit.

Opmerking:new-featuremoet een lokalevestiging zijn, geen externe.


Antwoord 3, autoriteit 3%

git checkout branch_name file_name

Voorbeeld:

git checkout master App.java

Dit werkt niet als uw filiaalnaam een ​​punt bevat.

git checkout "fix.june" alive.html
error: pathspec 'fix.june' did not match any file(s) known to git.

Antwoord 4, autoriteit 2%

Aanvullend op de antwoorden van VonC en chhh.

git show experiment:path/to/relative/app.js > app.js
# If your current working directory is relative than just use
git show experiment:app.js > app.js

of

git checkout experiment -- app.js

Antwoord 5

Alles over het uitchecken van bestanden of mappen in git

1. Hoe u een of meer bestandenof directoriesvan een andere branch uitcheckt of hash commit in uw momenteel uitgecheckte branch:

# check out all files in <paths> from branch <branch_name>
git checkout <branch_name> -- <paths>

Bron: http://nicolasgallagher.com/git- checkout-specific-files-from-another-branch/.

Zie ook man git checkout.

Voorbeelden:

# Check out "somefile.c" from branch `my_branch`
git checkout my_branch -- somefile.c
# Check out these 4 files from `my_branch`
git checkout my_branch -- file1.h file1.cpp mydir/file2.h mydir/file2.cpp
# Check out ALL files from my_branch which are in
# directory "path/to/dir"
git checkout my_branch -- path/to/dir

Als je niets opgeeft, wordt de branch_nameautomatisch aangenomen dat het HEADis, wat je meest recente commit is van de momenteel uitgecheckte branch. U kunt dit dus ook gewoon doen om “somefile.c” uit te checken en lokale, niet-vastgelegde wijzigingen te laten overschrijven:

# Check out "somefile.c" from `HEAD`, to overwrite any local, uncommitted
# changes
git checkout -- somefile.c
# Or check out a whole folder from `HEAD`:
git checkout -- some_directory

2. Verder gaan: hoe u een bestand uit een branch kunt uitchecken of hash kunt vastleggen op een willekeurige locatie op uw computer (HEEL NUTTIG!):

# General form
git show my_branch_or_commit_hash:my_file.cpp > any/path/my_file.cpp
# Example: check out `main.cpp` from 3 commits ago in your currently-checked-out
# branch (3 commits prior to `HEAD`, or `HEAD~3`) into a temporary directory
mkdir ../temp
git show HEAD~3:main.cpp > ../temp/main_old.cpp

Bron waar ik dit heb geleerd: @Jakub Narebski’s antwoord op: git-checkout oudere revisie van een bestand onder een nieuwe naam

3. Wat als je bezig bent met het oplossen van git merge, git cherry-pick, git rebaseof git revertwijzigingen?

Nou, in dat geval kun je beter dit doen:

# Keep `--theirs` for all conflicts within this file
git checkout --theirs -- path/to/some/file
# OR: keep `--ours` for all conflicts within this file
git checkout --ours -- path/to/some/file

OF:

# Keep `--theirs` for all conflicts within files inside this dir
git checkout --theirs -- path/to/some/dir
# OR: keep `--ours` for all conflicts within files inside this dir
git checkout --ours -- path/to/some/dir

Voer NIET het normale checkoutuit in het vorige gedeelte hiervoor, tenzij dat is wat u echt wilt doen.Zie de “WAARSCHUWING WAARSCHUWING WAARSCHUWING” in mijn antwoord hier: Wie is “ons” en wie is “hen” volgens Git?.

OMHANDEL MET path does not have our versionof path does not have their versionFOUTEN:

Als u ooit dergelijke fouten ziet:

error: path 'path/to/some/dir/file1.cpp' does not have our version
# OR
error: path 'path/to/some/dir/file1.cpp' does not have their version

…bij het uitvoeren van de bovenstaande commando’s, dan moet je gewoon eerst die bestanden git rmen dan git checkout --oursof git checkout --theirscommando opnieuw. Zie mijn antwoord hier voor een gedetailleerde uitleg van deze commando’s, inclusief een formulier om die foutieve bestanden automatisch voor je te vinden en te verwijderen: git checkout –ours wanneer bestandsspecificatie verwijderd bestand bevat.

4. Wat als je een bepaald bestand of map wilt resetten zodat het exact overeenkomtmet de status van dat bestand of die map in een andere commit of branch?

In dit geval is git checkout my_branch -- some_file_or_dirNIET genoeg, want als je bestanden in de gespecificeerde directory hebt die bestaan ​​in je momenteel uitgecheckte branch of commit maar NIET bestaan ​​in my_branch, dan zou je willen dat ze lokaal verwijderd worden, maar git checkoutverwijdertgeen bestanden die lokaal bestaan ​​maar niet op de gespecificeerde commit, in plaats daarvan overschrijft het alleenbestanden lokaal met hun versies van de gespecificeerde commit. Dus om ook lokaal bestanden te verwijderendie er niet zouden moeten staan, zodat je lokaal een exacte kopiekrijgt van wat je op my_branch, moet u het volgende doen:

git reset my_branch -- path/to/some/file_or_dir
git checkout-index -fa
git clean -fd
git commit -m "hard reset path/to/some/file_or_dir to its state \
as it was at my_branch"

Zie hier mijn eigen antwoord voor meer details hierover: Waarom kan git geen harde/zachte reset uitvoeren via pad?.

Zie ook:

  1. Ik laat wat meer van deze voorbeelden van git checkoutzien in mijn antwoord hier: Wie is “ons” en wie is “hen” volgens Git?.
  2. [mijn antwoord op “Hoe een –soft of –hard git reset via pad uit te voeren”] Waarom kan git geen harde/zachte resets doen via pad?
  3. git-checkout oudere revisie van een bestand onder een nieuwe naam
  4. [mijn antwoord] git checkout – -ours wanneer bestandsspecificatie verwijderd bestand bevat
  5. [mijn antwoord] Hoe reset je met git de werkboom (status van het lokale bestandssysteem) naar de status van de index (“gefaseerde” bestanden)?

Antwoord 6

Om een ​​bestand van een andere branch te herstellen, gebruik je gewoon het volgende commando vanuit je werkende branch:

git restore -s my-other-branch -- ./path/to/file

De vlag -sis een afkorting voor source, d.w.z. de vertakking van waaruit u het bestand wilt ophalen.

(Het gekozen antwoord is zeer informatief maar ook een beetje overweldigend.)


Antwoord 7

Of als je alle bestanden van een andere branch wilt:

git checkout <branch name> -- .

Antwoord 8

Bekijk het bestand op github en haal het daar vandaan

Dit is een pragmatische benadering die niet direct antwoord geeft op de OP, maar sommigen hebben het nuttig gevonden:

Als de betreffende branch op GitHub staat, dan kun je naar de gewenste branch en het gewenste bestand navigeren met een van de vele tools die GitHub biedt, dan op ‘Raw’ klikken om de platte tekst te bekijken, en (optioneel) kopiëren en plakken de tekst naar wens.

Ik vind deze aanpak leuk omdat je het externe bestand in zijn geheel kunt bekijken voordat je het naar je lokale computer trekt.


Antwoord 9

Een andere manier is om een ​​patch te maken met de verschillen en deze toe te passen in de master branch
Bijvoorbeeld. Laten we zeggen dat de laatste commit voordat je aan app.js begon te werken 00000aaaaa is en dat de commit met de gewenste versie 00000bbbbb is

Als je dit op de experiment-branch uitvoert:

git diff 00000aaaaa 00000bbbbb app.js > ~/app_changes.git

Hiermee wordt een bestand gemaakt met alle verschillen tussen die twee commits voor app.js die je kunt toepassen waar je maar wilt. U kunt dat bestand overal buiten het project bewaren

Vervolgens voer je in master gewoon uit:

git apply ~/app_changes.git

nu ga je de wijzigingen in de projecten zien alsof je ze handmatig had gemaakt.


Antwoord 10

Als je het bestand van een bepaalde commit (elke branch) wilt hebben, zeg 06f8251f

git checkout 06f8251f path_to_file

bijvoorbeeld , in vensters:

git checkout 06f8251f C:\A\B\C\D\file.h


Antwoord 11

git checkout master               -go to the master branch first
git checkout <your-branch> -- <your-file> --copy your file data from your branch.
git show <your-branch>:path/to/<your-file> 

Ik hoop dat dit je zal helpen.
Laat het me weten als je een vraag hebt.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

four × five =

Other episodes