Określanie ostatniej listy zmian zsynchronizowanej w Perforce


117

Czasami pojawia się pytanie, jaki jest najlepszy sposób określenia listy zmian, z którą ostatnio synchronizowałeś się w Perforce. Jest to często potrzebne do takich rzeczy, jak wprowadzenie numeru listy zmian do informacji o rewizji przez automatyczny system kompilacji.


p4 changes | head -1wydaje się łatwiejsze niż większość tych rozwiązań.
Sridhar Sarnobat

Odpowiedzi:


91

W przypadku systemów automatycznego budowania zalecam odwrotność: najpierw należy pobrać najnowszą listę zmian z serwera za pomocą:

p4 changes -s submitted -m1

następnie zsynchronizuj z tą zmianą i zapisz ją w informacjach o wersji. Powód tego jest następujący. Chociaż Perforce zaleca następujące czynności w celu określenia listy zmian, z którą synchronizowany jest obszar roboczy:

p4 changes -m1 @clientname

zauważają kilka pułapek:

  • Działa to tylko wtedy, gdy nie przesłałeś niczego z danego obszaru roboczego.
  • Możliwe jest również, że obszar roboczy klienta nie jest zsynchronizowany z żadną określoną listą zmian.

i jest dodatkowa pułapka, o której nie wspominają:

  • Jeśli najwyższa lista zmian, do której nastąpiła synchronizacja, to ściśle usunięte pliki z obszaru roboczego, zostanie zgłoszona następna w kolejności lista zmian (chyba że to również są ściśle usunięte pliki).

Jeśli musisz najpierw zsynchronizować, a później nagrać, Perforce zaleca uruchomienie następującego polecenia, aby określić, czy zostałeś pokonany przez powyższe pułapki; powinien wskazywać, że nic nie zostało zsynchronizowane ani usunięte:

p4 sync -n @changelist_number

Dlaczego jest tak, że „Działa to tylko wtedy, gdy nie przesłałeś niczego z danego obszaru roboczego”?
gdw2

Jeśli prześlesz zmianę, polecenie „p4 changes -s submitted -m1” zwróci numer listy zmian. Na przykład, powiedzmy, że synchronizujesz się z listą zmian 5, odczekaj kilka godzin, a następnie prześlij listę zmian 10. Powyższe polecenie zmian zwróci wartość 10.
Rinn

Link jest martwy, czy to ten artykuł? odpowiedzi.perforce.com/articles/KB/3458/
user31389

Zauważ, że możesz użyć #havezamiast @clientname, co pozwala uniknąć konieczności wyszukiwania nazwy obszaru roboczego klienta.
jojo

29

Aby odpowiedzieć na to pytanie, zgodnie z sugestią Jeffa, by używać Stackoverflow jako miejsca do przechowywania technicznych fragmentów ....

Z linii poleceń użyj:

p4 changes -m1 @<clientname>

I po prostu zastąp nazwą specyfikacji klienta. Spowoduje to utworzenie wyniku w postaci:

Change 12345 on 2008/08/21 by joebloggs@mainline-client '....top line of description...'

Które można łatwo przeanalizować, aby wyodrębnić numer listy zmian.


Otrzymuję: Zbyt duże żądanie (ponad 1500000); zobacz 'p4 help maxresults'.
user674669

@ user674669: użyj opcji -m1, która zwraca tylko ostatnią (1) listę zmian
panako

Daje to informacje o ostatnio przesłanej liście zmian , a nie o ostatniej zsynchronizowanej liście zmian , co chciał wiedzieć operator.
Andreas

@marsh Myślę, że w rzeczywistości jest to nazwa obszaru roboczego klienta, która domyślnie jest nazwą komputera, jeśli nie jest ustawiona. Zobacz tutaj: P4CLIENT .
Andreas Haferburg

15

Możesz spróbować znaleźć maksymalną liczbę zmian w danych wyjściowych polecenia „p4 files”. Katalog roboczy nie powinien jednak zawierać zatwierdzeń po synchronizacji. To jest tylko odrobinę lepsze niż

p4 changes -m1 "./...#have"

ponieważ ten ostatni wydaje się działać na serwerze i może zawieść na dużych drzewach źródłowych z powodu ograniczeń „MaxResults”.

$ p4 changes -m1 "./...#have"
Request too large (over 850000); see 'p4 help maxresults'.

$ p4 -G files "./...#have" | python c:/cygwin/usr/local/bin/p4lastchange.py
Files: 266948
2427657

gdzie p4lastchange.py jest oparty na kodzie z prezentacji Using P4G.py From the Command Line autorstwa JTGoldstone, Kodak Information Network / Ofoto, 15 kwietnia 2005.

#! /usr/bin/env python
import sys, os, marshal

if os.name == "nt":
    # Disable newline translation in Windows.  Other operating systems do not
    # translate file contents.
    import msvcrt
    msvcrt.setmode( sys.stdin.fileno(), os.O_BINARY )

lastcl = 0
num = 0
try:
    while 1:
        dict = marshal.load(sys.stdin)
        num = num + 1
        for key in dict.keys():
            # print "%s: %s" % (key,dict[key])
            if key == "change":
                cl = int(dict[key])
                if cl > lastcl:
                    lastcl = cl
except EOFError:
    pass
print "Files: %s" % num
print lastcl

10

Jeśli używasz P4V, możesz to zrobić graficznie:

  • W zakładce Pulpit nawigacyjny (Widok-> Pulpit nawigacyjny) wybierz folder, a zobaczysz listę list zmian, którymi folder nie został jeszcze zaktualizowany. Zwróć uwagę na najniższą liczbę (w najwyższym rzędzie).
  • Upewnij się, że w drzewie obszaru roboczego wybrałeś ten sam folder, co poprzednio na pulpicie nawigacyjnym. Następnie przejdź do zakładki Historia (Widok-> Historia) i przewiń w dół do numeru zanotowanego wcześniej. Liczba tuż pod tym numerem to numer Twojej bieżącej listy zmian.

9

p4 changes -m1 @clientname co jest „zalecanym” sposobem zrobienia tego dla mojego klienta zajmuje około 10 minut

tego używam:

p4 cstat ...#have | grep change | awk '$3 > x { x = $3 };END { print x }'

dla tego samego klienta zajmuje 2,1 sekundy


Jaka jest nazwa klienta? Jak mogę znaleźć te informacje?
bagno

1
@marsh client (lub również workspace) name to nazwa obiektu perforce, który przechowuje mapowanie z serwera depo do lokalnego systemu plików
gsf

2
Głosowanie za tą odpowiedzią, ponieważ odpowiada ona na rzeczywiste pytanie, a nie mówi „nie rób tego” (co jest ważne, ale nie odpowiada na pytanie).
sam hocevar

1
p4 changes -m1 @clientnamebiegać bez końca ... p4 cstat ...#have | grep change | awk '$3 > x { x = $3 };END { print x }'naprawdę działa! Dzięki!
simomo

@gsf - dzięki, właśnie wypróbowałem to na moim Linuksie i zadziałało!

8

Możesz także użyć polecenia cstat:

p4 help cstat

cstat -- Dump change/sync status for current client

p4 cstat [files...]

Lists changes that are needed, had or partially synced in the current
client. The output is returned in tagged format, similar to the fstat
command.

The fields that cstat displays are:

    change   changelist number
    status   'have', 'need' or 'partial'

5

W przypadku poważnej kompilacji (takiej, która jest przygotowywana do testowania), wyraźnie określ żądaną etykietę lub numer listy zmian , zsynchronizuj z etykietą i umieść ją w artefaktach kompilacji.

Jeśli lista p4 counter changezmian (lub etykieta) nie jest podana, użyj, aby uzyskać bieżący numer zmiany i zapisz go. Ale nadal musisz zsynchronizować wszystko za pomocą tego numeru zmiany.

Nie sądzę, że możesz osiągnąć dokładnie to, co chcesz, ponieważ ogólnie cały obszar roboczy nie jest zsynchronizowany z określonym numerem na liście zmian. Można jawnie zsynchronizować niektóre pliki ze starszymi wersjami, a wtedy pojedynczy numer listy zmian jest bez znaczenia. Dlatego syncpotrzebny jest nowy, aby mieć pewność, że pojedynczy numer listy zmian dokładnie reprezentuje wersję kodu.


Odnośnie komentarzy: Tak, moja odpowiedź jest przeznaczona dla menedżerów konfiguracji przygotowujących kompilację do kontroli jakości. Nasi programiści zwykle nie synchronizują się jako część kompilacji; robią kompilację przed przesłaniem - dzięki czemu mogą mieć pewność, że wprowadzone przez nich zmiany nie zakłócą kompilacji ani testów. W tym kontekście nie zawracamy sobie głowy osadzaniem etykiety repozytorium.

W swoim podejściu zakładasz, że cały obszar roboczy został zsynchronizowany z głową w momencie ostatniego przesłania listy zmian, a lista zmian zawierała wszystkie otwarte pliki. Zbyt łatwo jest się pomylić w tych założeniach, trudnych do wykrycia i potwornie kosztownych, jeśli chodzi o stracony czas. Z drugiej strony rozwiązanie problemu jest łatwe, bez wad. A ponieważ numer listy zmian można wyraźnie określić, nie ma znaczenia, jakiej wersji potrzebujesz ani jak szybko zmienia się baza kodów.


Erickson - fajna sugestia, ale myślę, że obejmuje nieco inny zestaw okoliczności niż odpowiedź, której udzieliłem. Z pewnością licznik zadziała, jeśli prawdopodobnie masz tylko wersję główną, a serwer nie jest wystarczająco zajęty, aby ktoś, być może pracujący nad innym projektem, nie wykonał przesłania między synchronizacją a wywołaniem licznika p4. Więc myślę, że twoja sugestia jest prawdopodobnie najlepsza, gdy system kompilacji wykonuje wyraźne pociągnięcie, a następnie kompilację. Moja odpowiedź obejmuje przypadki, w których synchronizacja może zostać oddzielona w czasie od kompilacji. Myślę, że oba są ważne w zależności od okoliczności.
Greg Whitfield,

3

Dla całego magazynu (nie tylko obszaru roboczego / klienta)

p4 counter change

wykonuje pracę, po prostu podaje ostatnią listę zmian.


2
Zauważ, że raport ten podaje liczbę najnowszej listy zmian magazynu, WŁĄCZAJĄC listy oczekujące (tj. Jeszcze nie przesłane). Tak więc każdy użytkownik rozpoczynający nową pracę w swoim kliencie wpłynie na ten numer. Będzie się to różnić od ostatniej listy zmian zsynchronizowanej z lokalnym obszarem roboczym.
jasonmray

2

Najlepsze, co do tej pory znalazłem, to zsynchronizowanie się z dowolną listą zmian, którą chcesz zbudować, a następnie użycie zmian -m1 //...#have, aby uzyskać aktualną lokalną listę zmian (wersję).

p4 sync @ CHANGELIST_NUM p4 changes -m1 //...#have | awk '{print $ 2}'

Podaje numer listy zmian, z którego możesz korzystać w dowolnym miejscu. Obecnie szukam prostszego sposobu niż zmiany p4 -m1 //...#have.


0

Nie jestem pewien, czy otrzymałeś odpowiedź, której potrzebujesz, ale miałem podobny problem. Celem było wpisanie do naszego loggera konkretnej wersji projektu. Problem polegał na tym, że kiedy tworzymy własny plik makefile, cały system budowania jest kontrolowany przez nasze zarządzanie konfiguracją. Oznacza to, że wszystkie rozwiązania, które mówią „zsynchronizuj z czymś, a następnie zrób coś”, tak naprawdę nie działają i nie chciałem ręcznie zmieniać wersji przy każdym zatwierdzeniu (pewne źródło błędów). Rozwiązanie (które jest faktycznie sugerowane w niektórych z powyższych odpowiedzi) jest następujące: w naszym pliku makefile robię p4 zmiany -m1 "./...#have" Wynikiem tego jest Zmień numer_zmianu na dzień przez użytkownika @ klient ' msg ' Po prostu tworzę wiadomość w ciąg, który jest drukowany przez rejestrator (numer zmiany jest ważnym elementem, ale drugi jest również przydatny, aby szybko zdecydować, czy dana wersja zawiera zmiany, o których wiesz, że dokonałeś samodzielnie, bez konieczności sprawdzania). Mam nadzieję że to pomoże.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.