SVN: esiste un modo per contrassegnare un file come "non eseguire il commit"?


153

Con TortoiseSVN, posso spostare un file nella lista dei cambiamenti di ignore-on-commit, in modo che quando eseguo il commit di un intero albero, le modifiche a quel file non vengono impegnate.

C'è un modo per fare qualcosa del genere usando lo strumento da riga di comando svn?

EDIT: Grazie per i suggerimenti da usare svn:ignore, ma non fa esattamente quello che stavo cercando.

svn:ignoreinfluenza cose come svn add& svn import. Fornisce un elenco di modelli di file da ignorare.

Ho un file che è già sotto il controllo del codice sorgente, ma voglio apportare modifiche temporanee a quel file che non voglio impegnare in seguito quando eseguo il commit dell'intero albero dei sorgenti. Sto apportando molte altre modifiche e potrei incollare una nota sul mio monitor che mi dice di ripristinare quel file prima di eseguire il commit dell'albero, ma sarebbe bello se svn potesse saltare automaticamente quel file.


1
Esiste un modo per utilizzare il ramo personale e cambiare lo stato. [Vedere il mio altro post su questo argomento.] [1] [1]: stackoverflow.com/questions/862950/...
ptitpion

Risposte:


120

Subversion non ha una funzione integrata "non eseguire il commit" / "ignora il commit", a partire da febbraio 2016 / versione 1.9. Questa risposta è una soluzione alternativa non ideale della riga di comando

Come afferma l'OP, TortoiseSVN ha un elenco di modifiche incorporato, "ignore-on-commit", che viene automaticamente escluso dai commit. Il client della riga di comando non ha questo, quindi è necessario utilizzare più elenchi modifiche per ottenere lo stesso comportamento (con avvertenze) :

  • uno per lavoro che vuoi impegnare [lavoro]
  • uno per le cose che vuoi ignorare [ignore-on-commit]

Dato che c'è un precedente con TortoiseSVN, nei miei esempi uso "ignore-on-commit" per i file che non voglio impegnare. Userò "lavoro" per i file che faccio, ma potresti scegliere qualsiasi nome tu voglia.

Innanzitutto, aggiungi tutti i file a un elenco modifiche denominato "lavoro". Questo deve essere eseguito dalla radice della tua copia di lavoro:

svn cl work . -R

Ciò aggiungerà ricorsivamente tutti i file nella copia di lavoro all'elenco delle modifiche denominato "lavoro". Ciò presenta uno svantaggio: poiché i nuovi file vengono aggiunti alla copia di lavoro, dovrai aggiungere in modo specifico i nuovi file o non verranno inclusi. In secondo luogo, se devi eseguirlo di nuovo, dovrai aggiungere nuovamente tutti i tuoi file "ignora-on-commit". Non ideale: potresti iniziare a mantenere il tuo elenco "ignora" in un file come hanno fatto altri.

Quindi, per i file che si desidera escludere:

svn cl ignore-on-commit path\to\file-to-ignore

Poiché i file possono essere solo in una lista modifiche, l'esecuzione di questa aggiunta dopo la precedente aggiunta "lavoro" rimuoverà il file che si desidera ignorare dalla lista modifiche "lavoro" e lo inserirà nella lista modifiche "ignora-on-commit".

Quando sei pronto per eseguire il commit dei file modificati che desideri eseguire il commit, aggiungi semplicemente "--cl work" al tuo commit:

svn commit --cl work -m "message"

Ecco come appare un semplice esempio sulla mia macchina:

D:\workspace\trunk>svn cl work . -R
Skipped '.'
Skipped 'src'
Skipped 'src\conf'
A [work] src\conf\db.properties
Skipped 'src\java'
Skipped 'src\java\com'
Skipped 'src\java\com\corp'
Skipped 'src\java\com\corp\sample'
A [work] src\java\com\corp\sample\Main.java
Skipped 'src\java\com\corp\sample\controller'
A [work] src\java\com\corp\sample\controller\Controller.java
Skipped 'src\java\com\corp\sample\model'
A [work] src\java\com\corp\sample\model\Model.java
Skipped 'src\java\com\corp\sample\view'
A [work] src\java\com\corp\sample\view\View.java
Skipped 'src\resource'
A [work] src\resource\icon.ico
Skipped 'src\test'

D:\workspace\trunk>svn cl ignore-on-commit src\conf\db.properties
D [work] src\conf\db.properties
A [ignore-on-commit] src\conf\db.properties

D:\workspace\trunk>svn status

--- Changelist 'work':
        src\java\com\corp\sample\Main.java
        src\java\com\corp\sample\controller\Controller.java
        src\java\com\corp\sample\model\Model.java
M       src\java\com\corp\sample\view\View.java
        src\resource\icon.ico

--- Changelist 'ignore-on-commit':
M       src\conf\db.properties

D:\workspace\trunk>svn commit --cl work -m "fixed refresh issue"
Sending        src\java\com\corp\sample\view\View.java
Transmitting file data .done
Committing transaction...
Committed revision 9.

Un'alternativa sarebbe quella di aggiungere semplicemente tutti i file che si desidera impegnare in un elenco di modifiche "lavoro" e non mantenere nemmeno un elenco ignorato, ma anche questo è molto lavoro. In realtà, l'unica soluzione semplice e ideale è se / quando questo viene implementato in SVN stesso. C'è un problema di vecchia data al riguardo nel tracker dei problemi di Subversion, SVN-2858 , nel caso in cui questo cambi in futuro.


1
Ho aggiunto due file con il comando che hai citato: $svn st --- Changelist 'ignore-on-commit': M database.php M config.php e ancora, sono stati inviati al repository su commit. Qualche idea di cosa ho fatto di sbagliato?
Attila Fulop,

7
L'aggiunta di file all'elenco modifiche 'ignore-on-commit' non impedisce di per sé il commit dei file. TortoiseSVN (un client con GUI di Windows) è stato creato nel rispetto di "ignore-on-commit", ma la riga di comando svn no. L'unico suggerimento che ho avuto nella mia risposta originale è stato quello di aggiungere i file che vuoi impegnare in un elenco di modifiche e dirgli di impegnarlo
Joshua McKinnon,

7
ignore-on-commit è sicuramente un elenco riservato di Tortoise. Tutto ciò che sta facendo è impedire che gli elementi vengano controllati nella GUI per impostazione predefinita, quindi è una funzionalità specifica della GUI di Tortoise. Non è necessario utilizzare la riga di comando per aggiungere all'elenco se si utilizza la GUI. Solo il menu di scelta rapida sugli elementi dell'elenco di commit e in fondo è possibile spostarli in un elenco modifiche e Ignora-su-commit è già definito. tortoisesvn.net/docs/release/TortoiseSVN_en/…
tjmoore

questo non ha fatto jack. ha commesso tutto.
ahnbizcad,

Non funzionante, la domanda posta specificamente su una soluzione a riga di comando, non sulla GUI.
riv

26

Ho sempre mi sono trovato in questa situazione troppo: e changelists non lavoro per me - voglio fare un breve elenco di file che io non voglio impegnare, invece di mantenere un elenco enorme di file che mi faccio volere commettere!

Lavoro sulla riga di comando di Linux: quindi la mia soluzione è creare uno script / usr / bin / svnn (sì, con due 'n!) Come segue:

#! /bin/bash
DIR=/home/mike/dev/trunk

IGNORE_FILES="\
        foo/pom.xml \
        foo/src/gwt/App.gwt.xml \
        foo/src/main/java/gwt/Common.gwt.xml \
        foo/src/main/resources/context/datasource/local.xml \
        foo/src/main/resources/context/environment/local.xml"

for i in $IGNORE_FILES; do mv $DIR/$i $DIR/"$i"_; done;

svn "$@"

for i in $IGNORE_FILES; do mv $DIR/"$i"_ $DIR/$i; done;

Ovviamente, questo è su misura per la mia situazione, ma basta cambiare DIR e IGNORE_FILES per adattarlo alla tua configurazione di sviluppo. Ricorda di cambiare lo script in eseguibile con:

sudo chmod +x /usr/bin/svnn

..quindi basta usare "svnn" invece di "svn" per eseguire la sovversione senza timore di controllare le modifiche locali ai file nell'elenco IGNORE_FILES. Spero che aiuti!


Infine, questa risposta è effettivamente giusta. Devi scrivere qualche strumento. Questo è in realtà imperfetto, perché voglio avere un'opzione dinamica, come svnn ignore configs/*- con caratteri jolly, campane e fischietti. Penso di scrivere qualcosa del genere da solo, e poi tornare qui!
Tomasz Gandor,

è fantastico! Ancora meglio, crea un alias in .bashrc per svn -> svnn. Ancora meglio, invece di specificare i file da ignorare all'interno del comando, potrebbe comportarsi come git, controllerebbe un file .ignore all'interno della cartella e ignorerebbe tutti i file che corrispondono allo schema.
Tarek,

Invece di dover reimparare la digitazione svnn, considera di chiamarlo svne posizionare questo script in qualcosa che può essere all'inizio del tuo PERCORSO, come ${HOME}/bin. Dallo script stesso, chiameresti /usr/bin/svn.
Joost

17

Non credo che ci sia un modo per ignorare un file nel repository. Spesso ci imbattiamo in questo con web.config e altri file di configurazione.

Sebbene non sia perfetta, la soluzione che vedo e utilizzo più spesso è quella di avere un file .default e un'attività nant per creare copie locali.

Ad esempio, nel repository è presente un file chiamato web.config.defaultcon valori predefiniti. Quindi creare un'attività nant che rinominerà tutti i web.config.defaultfile in modo web.configche possano essere personalizzati in base ai valori locali. Questa attività deve essere chiamata quando viene recuperata una nuova copia di lavoro o viene eseguita una build.

Dovrai anche ignorare il web.configfile creato in modo che non sia sottoposto a commit nel repository.


8

Dai un'occhiata alle liste delle modifiche , che possono fornirti un'opzione per filtrare i file che hai modificato ma che non vuoi impegnare. SVN non salterà automaticamente un file a meno che tu non lo dica a - e il modo in cui lo dici che questo file è in qualche modo diverso dagli altri file è quello di metterlo in un elenco di modifiche.

Richiede più lavoro per te e puoi solo applicare l'elenco delle modifiche alla tua copia di lavoro (ovviamente, immagina il caos che potrebbe derivare se tu potessi applicare una proprietà 'non aggiornare' a una revisione!).


1
Ma è esattamente quello che vogliamo. Ad esempio, un file di origine che è necessario impostare un defaultUserId = yourId, anziché il valore predefinito di sistema.
orbfish

4

Sono arrivato a questo thread alla ricerca di un modo per eseguire un commit "atomico" di solo alcuni file e invece di ignorare alcuni file su commit sono andato dall'altra parte e ho eseguito il commit solo dei file che volevo:

svn ci filename1 filename2

Forse aiuterà qualcuno.


La tua risposta è solo un suggerimento adeguato in questa discussione. svn ciè semplicemente un alias svn commit. Il comando Commit consente di eseguire il commit particolare dei file specificati
oxfn il

3

Ragazzi, ho appena trovato una soluzione. Dato che TortoiseSVN funziona nel modo che desideriamo, ho provato a installarlo su Linux, il che significa che funziona su Wine. Sorprendentemente funziona! Tutto quello che devi fare è:

  1. Aggiungi i file che vuoi ignorare eseguendo: "svn changelist 'ignore-on-commit'".
  2. Utilizzare TortoiseSVN per eseguire il commit: "~ / .wine / drive_c / Program \ Files / TortoiseSVN / bin / TortoiseProc.exe / command: commit / path: '
  3. I file esclusi saranno deselezionati per il commit per impostazione predefinita, mentre verranno controllati altri file modificati. Questo è esattamente lo stesso di Windows. Godere!

(Il motivo per cui è necessario escludere i file dalla CLI è perché la voce di menu per farlo non è stata trovata, non so perché. In ogni caso, funziona alla grande!)


2

Non è possibile eseguire il commit di file in conflitto. Puoi trarne vantaggio per mantenere le tue modifiche private fuori dal repository. Funziona meglio con un piccolo numero di file.

Per ottenere un conflitto a-file, la copia di lavoro (WC) non ha l'aggiornamento a-filedal repository e che a-filenel WC ha modifiche che si trovano nella stessa posizione delle modifiche nel repository (modifiche che non sono state aggiornate ancora). Se non si desidera attendere le condizioni di cui sopra, è possibile creare un conflitto in a-filequesto modo:
nella copia di lavoro 1 (WC1), aggiungere una riga di testo all'inizio a-file, ad esempio "crea un conflitto qui" . Utilizzare la sintassi necessaria in modo da non interrompere il repository. Commit a-fileda WC1. In WC2, aggiungi una riga di testo diversa nella parte superiore di a-file, come "Voglio un conflitto" . Aggiornamento da WC2 e ora un file dovrebbe essere in conflitto.


1

Vorrei invece scrivere uno script di supporto bash che viene eseguito svn commitsu tutti i file necessari e nessuno di quelli che non lo fanno. In questo modo hai molto più controllo.

Ad esempio, con una riga, puoi eseguire il commit di tutti i file con estensione .he .cppai quali hai apportato modifiche (e che non causerebbero un conflitto):

svn commit -m "" `svn status | grep "^M.*[h|cpp]$" | awk '{print $2}' | tr "\\n" " "`

Modifica / aggiungi estensioni alla [h|cpp]parte. Aggiungi un messaggio di registro tra le virgolette di -m ""se necessario.


1

Alcune delle idee proposte possono essere implementate in questo modo:

Su Windows in PowerShell

aggiungi tutto a default list.ps1

dir -Recurse | ? { -not $_.PSIsContainer } | % { svn cl default $_.FullName }

aggiungi per ignorare list.ps1

 dir file1 ... filN  % { $_.FullName } > ignore-on-commit
 cat .\ignore-on-commit | % { svn cl ignore-on-commit $_ }
 svn add ignore-on-commit

Ora puoi alias in svn ci --changelist defaultmodo da non doverlo specificare ogni volta. Il vantaggio aggiuntivo è che è possibile memorizzare l'elenco ignore-on-commit (se lo si desidera) nel repository.

Lo faccio per alcuni file che vengono costantemente rigenerati ma raramente effettivamente modificati a mano. Ad esempio, aggiungo un numero di revisione ai miei file di configurazione su segnaposto specifici, in modo che i file vengano cambiati ad ogni commit, ma la modifica manuale è rara.


1

Mi sono stancato di aspettare che questo fosse integrato in SVN. Stavo usando tortoiseSVN con ignore-on-commit, ma viene visualizzata una finestra di dialogo utente che non è possibile eliminare dalla riga di comando e quando eseguo il mio script di build e vado a fare una tazza di tè, lo odio quando Torno a scoprire che sta aspettando l'input dell'utente del 10%.

Quindi, ecco uno script PowerShell di Windows che esegue il commit solo dei file che non sono in una lista modifiche:

# get list of changed files into targets
[XML]$svnStatus = svn st -q --xml C:\SourceCode\Monad
# select the nodes that aren't in a changelist
$fileList = $svnStatus.SelectNodes('/status/target/entry[wc-status/@item != "unversioned"]') | Foreach-Object {$_.path};
# create a temp file of targets
$fileListPath =  [IO.Path]::GetTempFileName();
$fileList | out-file $fileListPath -Encoding ASCII
# do the commit
svn commit --targets $fileListPath -m "Publish $version" --keep-changelists 
# remove the temp file
Remove-Item $filelistPath

1

Aggiornamento dello script di user88044.

L'idea è di inserire i file nella lista delle modifiche da non commettere ed eseguire la sceneggiatura malvagia.

Lo script estrae i file do-not-commit dal comando: svn status --changelist 'do-not-commit'

#! / bin / bash DIR = "$ (pwd)"

IGNORE_FILES = "$ (svn status --changelist 'do-not-commit' | tail -n +3 | grep -oE '[^] + $')"

per i in $ IGNORE_FILES; fare $ DIR / $ i $ DIR / "$ i" _; fatto;

svn "$ @";

per i in $ IGNORE_FILES; fare $ DIR / "$ i" _ $ DIR / $ i; fatto;

Lo script è inserito in / usr / bin / svnn (sudo chmod + x / usr / bin / svnn)

stato svnn, svnn commit, ecc ...


1

È possibile configurare l'elenco modifiche "ignore-on-commit" direttamente con TortoiseSVN. Non è necessario configurare nessun altro elenco modifiche incluso tutti gli altri file

1) Fare clic su "SVN Commit ..." (non ci impegneremo, solo un modo per trovare un menu grafico per l'elenco delle modifiche) 2) Nell'elenco Fare clic con il pulsante destro del mouse sul file che si desidera escludere. 3) Menu: passa all'elenco modifiche> ignore-on-commit

La prossima volta che esegui un commit SVN ... I file appariranno deselezionati alla fine dell'elenco, nella categoria ignore-on-commit.

Testato con: TortoiseSVN 1.8.7, Build 25475-64 Bit, 2014/05/05 20:52:12, Subversion 1.8.9, -release


1
ragazzi, ho appena visto i commenti di tjmoore, già dando le buone informazioni per l'utente di tortoiseSVN ... nessuna riga di comando tortoisesvn.net/docs/release/TortoiseSVN_en/…
luney,

È rotto in 1.9?
Jake Hm,

1

Questo è in ritardo al gioco, ma ho trovato il comando da riga di comando più fantastico per questo problema. Fatto usando bash. Godere.

svn status | grep -v excluding | sed 's/^A */"/g; s/$/"/g' | tr '\n' ' ' | xargs svn commit -m "My Message"

Ok, quindi ecco una spiegazione del comando. Alcune cose dovranno essere cambiate in base al tuo caso d'uso.

svn status

Ottengo un elenco di tutti i file. Inizieranno tutti con quei caratteri di stato (?,!, A, ecc.). Ognuno è sulla propria linea

grep -v excluding

Uso grep per filtrare l'elenco. Può essere usato normalmente (per includere) o con il flag -v (per escludere). In questo caso, viene utilizzato per escludere, con una frase "escludendo" che sarà ciò che verrà escluso.

sed 's/^. */"/g; s/$/"/g'

Ora rimuovo il carattere di stato e lo spazio bianco all'inizio di ogni riga e quindi cito ogni riga, usando sed. Alcuni dei miei nomi di file hanno degli spazi, quindi la citazione.

tr '\n' ' '

Usando tr, sostituisco tutte le newline con spazi. Ora il mio intero elenco di file da impegnare è su una riga.

xargs svn commit -m "My Message"

Infine, uso xargs per eseguire il mio comando di commit con il messaggio. Fa il commit e rilascia il mio elenco di file citato come ultimo argomento.

Il risultato è che alla fine tutto funziona come voglio io. In qualche modo odio svn per avermi costretto a saltare attraverso questi dannati cerchi, ma posso conviverci. Suppongo.


0

Dato che stavo affrontando lo stesso identico problema, e il mio googling continuava a non darmi nulla, penso di aver trovato una soluzione alternativa. Ecco cosa ho fatto, sembra funzionare per me, ma dato che sono bloccato con una vecchia versione di SVN (<1.5, in quanto non ha l'opzione --keep-local) e non ne sono esperto , Non posso essere sicuro che sia una soluzione universale. Se funziona anche per te, fammi sapere!

Avevo a che fare con un'installazione Prestashop ottenuta da SVN, poiché altre persone avevano già iniziato a lavorarci. Poiché le impostazioni del DB sono state eseguite per un altro server, le ho modificate in alcuni file nella cartella / config. Poiché questa cartella era già sottoposta a versione, impostandola in svn: ignore non impedirebbe il commit delle mie modifiche locali su di essa. Ecco cosa ho fatto:

cp config ../cfg_bkp              # copy the files out of the repo
svn rm config                     # delete files both from svn and "physically"
svn propset svn:ignore "config" . # as the files no longer exists, I can add my ignore rule and then...
mv ../cfg_bkp config              # ...bring'em back
svn revert --recursive config     # make svn forget any existing status for the files (they won't be up for deletion anymore)

Ora posso eseguire svn add --force. nella radice del repository senza aggiungere la mia configurazione, anche se non corrisponde alla versione del repository (suppongo che avrei dovuto ripetere tutto questo se lo avessi modificato ancora una volta, senza testarlo). Posso anche aggiornare svn senza che i miei file vengano sovrascritti o che non ricevano errori.


0

Una soluzione che non ignora le modifiche nelle proprietà della directory

Ho provato a utilizzare la soluzione in base changelist, ma ho un paio di problemi con esso. Innanzitutto il mio repository ha migliaia di file, quindi l'elenco delle modifiche da impegnare è enorme e il mio svn statusoutput è diventato troppo lungo e ha bisogno di essere analizzato per essere utile. La cosa più importante è che volevo eseguire il commit delle modifiche provenienti da un'unione, il che significa che includono modifiche alle proprietà. Quando si esegue il commit di un elenco modifiche, le proprietà svn associate alla directory non vengono impegnate, quindi ho dovuto eseguire un commit aggiuntivo:

svn ci --cl work -m "this commits files from the work changelist only"
svn up
svn ci --depth empty DIR . -m "record merge properties"

Potrebbe essere necessario farlo per diverse directory (qui registro le proprietà di DIRe della directory corrente .), fondamentalmente quelle con a Mnella seconda colonna durante l'emissione del svn statuscomando.

Soluzione

Ho usato patch e svn patch. In pseudo-codice:

svn diff $IGNORE_FILES > MYPATCH   # get the mods to ignore
svn patch --reverse-diff MYPATCH   # remove the mods
svn ci -m "message"                # check-in files and directory properties
svn patch MYPATCH                  # re-apply the mods

Come altri poster, finisco per usare uno script per mantenere l'elenco dei file da ignorare:

#! /usr/bin/env bash

finish() {
    svn patch MYPATCH               # re-apply the mods
}
trap finish EXIT

IGNORE_FILES="\
sources/platform/ecmwf-cca-intel-mpi.xml \
runtime/classic/platform/ecmwf-cca.job.tmpl \
runtime/classic/platform/ecmwf-cca-intel.xml"

svn diff $IGNORE_FILES > MYPATCH # get the mods to ignore
svn patch --reverse-diff MYPATCH # remove the mods

svn "$@"

In genere l'ho usato con cie revert -R ..


-1

svn:ignore è la tua risposta.

Esempio:

$ svn propset svn:ignore -F .cvsignore .
property 'svn:ignore' set on '.'

1
Nota, l'esempio sopra mostra come usare un file cvsignore precedentemente configurato come input per la tua proprietà svnignore.
Ben Hoffstein,

1
no svn: ignore è solo per i file unversion. non funziona con i file di versione
Sérgio,

1
E anche non è locale. È un cambio di proprietà che verrà eseguito da solo.
Adam Badura,

-9
svn propset "svn:ignore" "*.xml" .

il *.xmlè il modello di file da ignorare; puoi usare anche i nomi delle directory qui.


3
-1 perché non è possibile ignorare un file che fa parte del repository.
zellus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.