Ta bort en stor binärfil från Din Git-historik för att hantera storleken på klonade lagringsplatser

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Git är en populär lagringsplats för distribuerad källkod (lagringsplats) som låter användare arbeta med den fullständiga lagringsplatsen när de är i frånkopplat tillstånd. Fördelarna med Git är väldokumenterade, men vad händer om du behöver "rulla tillbaka klockan" på den primära lagringsplatsen? Det är inte intuitivt och kräver utökade behörigheter. Det här kravet förväntas för något som påverkar varje enskild användare av lagringsplatsen.

Hur kan du gå tillbaka till det centrala repository på ett säkert sätt?

Problemscenario

Anta att du checkar in en stor fil, till exempel en video, på Din Git-server. I ett traditionellt källkodssystem är det praktiskt att lagra allt på ett ställe och sedan hämta det du behöver. Med Git klonas hela lagringsplatsen till varje användares lokala dator. Med en stor fil måste varje enskild användare i projektet också ladda ned de stora filerna.

Med varje efterföljande stor fil som överförts till servern växer problemet ytterligare. Lagringsplatsen blir för stor för att vara effektiv för sina användare. Även om du tar bort den stora filen från din lokala lagringsplats och återupptar den, finns filen fortfarande i lagringsplatsens historik. Därför laddas filen fortfarande ned till allas lokala dator som en del av historiken.

Skärmbild som visar dialogrutan Ändringar i Team Explorer med en stor video i inkluderade ändringar.

Lägg till en stor fil på den lokala lagringsplatsen.

Skärmbild som visar server- och lokala lagringsplatser, båda med en kopia av de stora videofilerna.

När du committerar från det lokala repot, har servern även den stora filen.

Lås lagringsplatsen

För att åtgärda problemet med en stor lagringsplats måste du börja vid källan. I det här scenariot är källan serverns lagringsplats. Be teamet att sluta skicka till lagringsplatsen. Om fler push-åtgärder sker under den här processen måste du ta hänsyn till dem så att du inte förlorar några data.

Viktigt!

Följande steg tar bort videon från din grenhistorik, men filen finns kvar i lagringsplatsens historik när du klonar lagringsplatsen från Azure Repos. Om du tar bort filerna från din grenhistorik förhindras att filerna uppdateras, vilket skapade en annan version av den stora filen på lagringsplatsen.

Läs mer om att hantera stora filer i Git. En förklaring och lösning för det här beteendet när du använder Git-lagringsplatser för Azure Repos finns i Varför returnerar kloning från Visual Studio Team Services gamla orefererade objekt?.

Ändra bas och framtvinga push-överföring

Om ingen annan i teamet har gjort några ändringar i lagringsplatsen, som vanligtvis sker via en push-överföring, kan du ta den enkla vägen. Du får i princip din lokala lagringsplats att se ut som du vill att den ska se ut (alltså utan den stora filen). Sedan för upp du ändringarna till servern.

Du kan behöva klona eller åtgärda din lokala lagringsplats innan du påbörjar det här arbetet. Den här processen kan leda till förlorat arbete eller ändringar, så fortsätt med försiktighet.

Som standard kan du ändra lokala projektfiler och skicka ändringar till servern, men du kan inte utföra åtgärder på servernivå som borttagning eller ombasering. För att fortsätta behöver du force push (rekommenderas) eller administratörsbehörigheter på repository. Kontakta projektadministratören för att begära dessa behörigheter eller be någon som redan har dem att hjälpa till. Mer information finns i Ange Behörigheter för Git-lagringsplats.

Skärmbild som visar kommandotolken – git push --force-behörigheter.

Därefter måste du ändra lagringsplatsens bas.

  1. Använd git log för att hitta SHA-hashvärdena (Secure Hash Algorithm) för de senaste ändringarna. Du behöver den här informationen om en stund eftersom du behöver veta den senaste bra commit. Du kan hämta den informationen genom att öppna en Git-kommandotolk och ange:

    git log

    Du kan också hämta SHA-hashen från att visa grenhistoriken i Visual Studio Team Explorer.

    Skärmbild som visar alternativet Visa historik för huvudgrenen.

  2. Öppna en Git-kommandotolk.

    Skärmbild som visar åtgärden Öppna kommandotolken i dialogrutan Synkronisering.

  3. Hitta SHA-hashantalet av intresse.

    Skärmbild som visar kommandotolken för videoincheckningen.

    Du behöver den SHA som startar 25b4.

    Kom ihåg att Git använder pekare för att avgöra var i lagringsplatsen huvudet eller den aktuella grenen finns. Repostatusen du är intresserad av finns vid en tidpunkt i det förflutna.

  4. Om du vill gå tillbaka i tiden och göra det tidigare tillståndet till det nya aktuella tillståndet använder du git rebase kommandot:

    git rebase -i <SHA hash of desired new current branch>

    Skärmbild som visar hur du använder rebase för att ta bort videofilen.

    Växeln -i ger extra säkerhet eftersom den tar upp historiken i en redigerare. (Den här artikeln använder en implementering av Git som tar upp den klassiska vi-redigeraren på kommandoraden i Windows. Du kanske kommer ihåg det om du arbetade med ett Unix-baserat system.)

  5. I det här exemplet anger du:

    git rebase -i 25b4

  6. När redigeraren visas tar du bort alla pick rader förutom den gren du vill behålla som din nya huvudgren. När allt ser korrekt ut anger du :w\<enter\> i vi för att spara eller ange !q\<enter\> för att avsluta utan att spara.

    Skärmbild som visar kommandotolken – git rebase -i 25b4 pick command.

    Ändra de rader som du inte längre vill ha.

    Skärmbild som visar kommandotolken – git rebase -i 25b4 drop-kommando.

  7. Ändra pick till drop som visas. Ange :w (i vi) för att spara och ange :q! för att starta rebase-processen.

    Ange git log nu igen. Den felande grenen bör vara frånvarande från loggen. I så fall är du redo för det sista steget, som kräver projektadministratörsbehörighet:

    git log

    Skärmbild som visar lokala lagringsplatser och serverlagringsplatser efter ombasering.

    Incheckningen för den stora videon är nu borta från den lokala lagringsplatsen.

  8. Ange följande kommando:

    git push --force

    Skärmbild som visar kommandotolken – git push --force.

    Skärmbild som visar kommandotolken – git push --force-resultat.

    Det här kommandot forcerar ditt förråd att skriva över förrådet på servern.

    Använd det här kommandot med försiktighet eftersom du enkelt kan förlora data på servern.

    Skärmbild som visar en forcerad push som visar innehåll som ska behållas, utan den stora videofilen.

Du måste autentisera till servern för att den här åtgärden ska fungera.

Om du använder Azure Repos kan du behöva konfigurera en alternativ autentiseringsuppgift som inte använder specialtecken. Ett exempel är at-symbolen (@) i en e-postadress. Följ anvisningarna i Autentisering med Azure-lagringsplatser för att utföra den här uppgiften.

Nu är grenen permanent borta från servern. Efterföljande kloner och synkroniseringar av projektteamets medlemmar laddar inte ned de stora filer som du försökte ta bort. Användarna måste hämta från servern för att se till att de är synkroniserade med det nya serverrepotillståndet.

Om användare har nyare åtaganden

Om andra användare har överfört commitar till serverns repo, måste du ta hänsyn till detta. Du vill ta bort grenen som innehåller de stora filerna, men du vill inte förlora ändringar som teamet har gjort. När du öppnar redigeraren som en del av ombaseringen bör du titta noga på ändringarna. Kontrollera att de commits du vill behålla finns listade på raderna pick. Ta bort de som du vill ta bort, till exempel var en stor fil har lagts till.

Efter ombaseringen måste de andra användarna i teamet också ombasera så att alla har en konsekvent kopia av serverdatabasen. Det här arbetet är tråkigt för alla, och du vill undvika det. Om du behöver ta bort en push måste du samordna med teamet. Mer information om ombasering finns i Git-förgreningar – ombasering.

Nyckeln är att se till att du känner till de åtaganden du vill ha och de åtaganden du inte vill ha. Studera git log eller historiken i din integrerade utvecklingsmiljö (till exempel Visual Studio). Anteckna noggrant SHA-hashvärdena som ska sparas och de hashvärden som ska tas bort.

I scenarier där den stora filen är gammal och det fanns efterföljande grenar och sammanslagningar kanske du kan ta bort filen med hjälp av växeln git filter-branch . Mer information finns i Ta bort känsliga data från en lagringsplats.

Överväganden för bästa praxis

Se till att stora filer håller sig borta från huvudlagringsplatsen för att spara gruppmedlemmar från extra arbete. Här följer några vanliga metodtips för teamet att tänka på.

Saker att göra

  • Genomför ändringar ofta. Du kan alltid fixa dem senare med en squash eller rebase.
  • Använd grenar för att isolera dina ändringar. Grenar är billiga och privata, och sammanslagning är enkel. Du kan också säkerhetskopiera ändringar på en gren genom att skicka dem till servern.
  • Använd en namngivningskonvention när du publicerar ämnesgrenar. Ge grenen users/<alias>/<branchname>namnet . Det här namnet hjälper dig att gruppera dina grenar och gör det enkelt för andra att identifiera ägaren.
  • Kom ihåg att pusha ändringarna. Använd Commit != Checkin och (Commit + Push) == Checkin.
  • Överväg att använda .gitignore för stora binärfiler så att de inte läggs till på lagringsplatsen. Mer information finns i Ignorera filer.
  • Överväg att använda versionskontroll för NuGet eller Team Foundation Server för att lagra dina stora binärfiler.

Saker att undvika

  • Förbasera inte igen efter push-överföring. Det kan vara dåligt att ombasera pushade commits i Git eftersom det tvingar alla andra i depån att ombasera sina lokala förändringar. Teammedlemmar kanske inte är nöjda om de behöver utföra den här uppgiften. Att ombasera push-incheckningar på din egen personliga gren, även om det pushas, är inte ett problem om inte andra personer drar dessa incheckningar.
  • Lägg inte in binärfiler i ditt repository. Git komprimerar inte binära filer på det sätt som Versionskontroll för Team Foundation gör. Eftersom alla lagringsplatser har hela historiken innebär incheckning av binära filer permanent uppsvälldhet.

Sammanfattning

Ibland läggs oönskade element, till exempel stora filer, till på en lagringsplats och måste tas bort för att lagringsplatsen ska vara ren och lätt. Du kan utföra den här uppgiften genom att få ordning på din lokala lagringsplats. Använd git rebase-kommandot, och sedan använda git push --force-kommandot för att skriva över server-repon med din lokala repo.