OCA Java core API

String

Operator + jest przeciążony: dla argumentów numerycznych to dodawanie, jeśli chociaż jeden z argumentów jest Stringiem jest to konkatentacja.

Przez niezmienność Stringów operacje na nich wykonane zwracają nowy obiekt.

Stringi utworzone przez dodawanie stałych są, w czasie kompilacji, zamieniane na stałe.

Stringi które powstały z wykorzystaniem niefinalnej zmiennej powstają w czasie uruchomienia więc nie są umieszczane w puli. Można je tam umieścić przez wywołanie intern(), metoda zwraca referencje do łańcucha o tej samej zawartości ale umieszczonego w puli.

"0123".substring(4) da w wyniku pusty String ale "0123".charAt(4) rzuci wyjątek, tak samo jak "0123".substring(5).

Operator ++ nie działa dla Stringa, mimo że "napis"+1 da w wyniku napis1.

toString() z Object zwraca String klasaZeScieżką;@hashCodeObiektu, jeśli klasa jest poprzedzona [L – referencja wskazuje tablicę obiektów tego typu [Ljava.langString;@120bc123.

indexOf przyjmuje Stringa lub znak jako int.

Metody które rzucają StringIndexOutOfBoundsExcepion delete, deleteCharAt, replace, insert, substring
Metody które rzucają bardziej ogólny IndexOutOfBoundsExcepion append, insert, setLength, charAt, codePointAt, codePointBefore, codePointCount, offsetByCodePoints, getChars, setCharAt, subSequence. W praktyce wszystkie te metody rzucają szczegółowy wyjątek, ale to może się zmienić i dalej będą zgodne z dokumentacją.


StringBuilder

Obiekt o zmiennej zawartości, domyślna pojemność to 16 znaków.

equals porównuje referencje a nie zawartość.

setLength może obciąć łańcuch lub dopełnić go za pomocą null character ’\u0000′.

indexOf przyjmuje Stringa.

append przyjmuje wszystko poza short i byte.


Tablice

W momencie dodawania elementu do tablicy sprawdzany jest typ obiektu i może zostać rzucony ArrayStoreException. Jest to spowodowane kowariancyjnością tablic.

Tablica Stringów jest podtypem tablicy Obiektów.

Tablica dwuwymiarowa to tablica kolumn (które też są tablicami) dlatego nie muszą być prostokątne.

Tablice wielowymiarowe podczas deklaracji wymagają podania tylko pierwszego wymiaru.

Tablica może być zadeklarowana przez String [] tab = {„a”, „b”} tylko w momencie inicjalizacji, w innych miejscach będzie to błąd kompilacji i trzeba to zrobić przez tab = new String[] {„a”, „b”}.

Puste tablice dwuwymiarowe można zainicjalizować przez jedną parę nawiasów.

java.util.Arrays zawiera narzędzia do sortowania, przeszukiwania i wyswietlania tablic. Arrays.binarySech zwraca pozycję elementu lub indeks miejsca w którym zostałby dodany -1.

Tablice nie przeciążają equals za to domyślnie implementują Serializable i Cloneable.


ArrayList

add() zawsze zwraca true.

ArrayList rozszerza AbstractList – szkieletową implementacje listy z dostępem do dowolnego elementu która umożliwia sekwencyjne dodawanie elementów, czyszczenie całej listy, łączenie list (addAll()), Iterator, subList(), equals(), hashCode()
Odpowiednik dla dostępu szeregowego to AbstractSequentialList.

remove(Object object) mówi czy usunięcie miało miejsce
remove(int index) zwraca usuwany element lub rzuca IndexOutOfBoundsException.

set(int index, E newElement) nadpisuje i zwraca zastąpiony element.


Typy opakowujące

Wszystkie typy są niezmienne. Wszystkie mają cache który przechowuje wartości od -128 do 127 (węższy zakres mają Character i Boolean, Integer ma konfigurowalny górny zakres). Cache jest wykorzystywany przez valueOf() który jest wywoływany przy tworzeniu literałów i podczas autoboxingu.

Integer.parseInt(String string) zwraca typ prosty (analogicznie dla innych typów opakowujących).

Autoboxing ma niższy priorytet w dopasowaniu parametrów niż bezpośrednie dopasowanie
listaIntegerow.remove(1) usunie pierwszy element
listaIntegerow.remove(new Integer(1)) usunie obiekt o wartości 1.


java.time

LocalDate przechowuje datę, LocalTimeprzechowuje czas, LocalDateTime przechowuje oba.
Wszystkie te obiekty są niezmienne, konstruowane przez statyczne metody, implementują TemporalAccessor którego zaleca się nie stosować.

LocalDate.of(int rok, int miesiąc, int dzień) miesiące są numerowane od 1 i mogą być zastąpione przez enuma Month.

LocalDateTime.of(rok, miesiąc, dzień, godzina, minuta, sekunda) lub LocalDateTime.of(data, czas).

Utworzenie daty przez podanie błędnych parametrów jest wykrywane dopiero w czasie uruchomienia (DateTimeException).

Wszystkie obiekty mają fluent API do dodawania lub odejmowania wartości (zwracają nowy obiekt).

LocalDate nie ma metod do modyfikowania czasu.

Period

Period.ofYears, Period.ofMonths, Period.ofWeeks, Period.ofDays tworzą obiekty okresu które można dodawać/odejmować od daty.

Okresy nie mają fluent API to tworzenia (tak samo jak Local*Time) of() to statyczne metody zwracające nowy obiekt. Przy próbie użycia of() jak fluent API tylko ostatnia instrukcja ma znaczenie.

Obiekt Period bierze pod uwagę zmiany strefy czasowej lub czasu na letni/zimowy. Analogiczny obiekt przechowujący bezwzględny okres to Duration.

DateTimeFormatter to obiekt opisujący formatowanie dla czasu. Formatowaniu można przekazać datę lub odwrotnie (dawne SimpleDateFormat).

Źródła:
„OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam 1Z0-808” Jeanne Boyarsky, Scott Selikoff
„JA+ V8 for Oracle Certified Associate – Java SE8 Programmer I” http://enthuware.com

OCA Operatory i instrukcje

Priorytety operatorów

– indeks tablicy, wywołanie metody i odwołanie do pola po kropce
– post-unary ++,+
– pre-unary --, -
– reszta jednoargumentowych (!, ~ – bitowa negacja)
– rzutowanie, new
– mnożenie / dzielenie / modulo
– dodawanie/ odejmowanie
– przesunięcia bitowe
– relacyjne
– równość / nierówność, instanceof
– operatory logiczne
– podwójne operatory logiczne
– operator trójargumentowy
– przypisania (compound)

Pojedyncze operatory logiczne & i | na typach logicznych mają działanie logiczne na numerycznych to operacje bitowe.

Wartość ujemna jest tworzona przez negacje binarną wartości dodatniej (kodowanie U2). Negacja binarna neguje bity i dodaje 1 więc Integer.MIN_VALUE == -Integer.MIN_VALUE.


Rzutowanie

Przy operacji na dwóch różnych typach prostych mniejszy jest promowany do większego.

Typy proste są automatycznie opakowywane, typy opakowujące są automatycznie rozpakowywane.

byte, short i char są promowane do int przy dwuargumentowych operacjach arytmetycznych
System.out.println('a') wyswietla literę
ale System.out.println('a' + 1 ) wyswietla 98.

Kompilator nie pozwala na niejawne rzutowanie w dół (jest wyjątek patrz niżej), jawne rzutowanie na typ całkowity ucina część ułamkową, w obrębie typów całkowitych bierze tylko tyle najmniej istotnych bitów ile może.

Niejawne rzutowanie w dół ma miejsce dla całkowitych zmiennych finalnych (lub literałów) mieszczących się w zakresie docelowego typu.

short i char mają różne zakresy (poza powyższym przypadkiem potrzebne jest rzutowanie).

x+=y to tak naprawdę x =(typ y) x + y ma znaczenie jeśli argumenty są różnych typów.

Można rzutować typy proste na opakowujące
int i = 1; (Integer) i.

Można rzutować nulla.

Można rzutować wszystkie niefinalne klasy na interfejs. Któraś podklasa może implementować ten interfejs, więc kompilator dopuszcza rzutowanie.

Przy wywoływaniu metod (rzutowanie parametru) występują dodatkowe warunki.


Operator trójargumentowy

Wykonuje tylko jedną z dwóch instrukcji.

Instrukcja może być kolejnym operatorem trójargumentowym.

Jeśli ma argumenty byte i short – wynik to short.

Jeśli ma argumenty byte, short lub char a drugi to literał (int) możliwy do zapisania w pierwszym – wynik to pierwszy typ.

W innych przypadkach typy muszą być możliwe do konwersji inaczej występuje błąd kompilacji.


Pętle

Nie można przesłaniać zmiennych w pętli for, wszystkie deklarowane zmienne muszą być tego samego typu. Przecinek nic nie zmienia – typ musi się pojawić tylko raz.

Zmienne zadeklarowane w bloku do nie są widoczne w warunku while.

Foreach działa tylko dla obiektów implementujących Iterable.

while nie wymaga średnika, do-while wymaga po warunku, żadne z nich nie wymaga {}.


Etykiety

Pętle, switche i warunki mogą mieć etykiety nazwa: instrukcja. Wykonanie wewnątrz break nazwa przenosi wykonanie do następnej instrukcji po bloku oznaczonym etykietą.


Switch

Pusty switch {} jest ok, zmienna musi być wystarczająco pojemna żeby pomieścić wszystkie przypadki, przypadki nie mogą się powtarzać. Long nie może być w switchu.

Switch jako wartość przed dwukropkiem dopuszcza tylko te znane w momencie kompilacji (literały, zmienne finalne zadeklarowane i zainicjalizowane w jednej instrukcji oraz enumy).

Zmienne to: całkowite typy numeryczne + char oraz ich typy opakowujące, enumy, Stringi (Java 7).

Zmienna zadeklarowana w jednym wpisie case switcha jest zadeklarowana (ale nie zainicjalizowana) także w innych. Dodanie nawiasów klamrowych po case zawęża zakres (wtedy powyższy przypadek nie ma miejsca) ale break; i tak jest wymagane.


Referencje

Przypisanie ma wartość prawej strony (z=1; x =y = ++z; wszystkie zmienne są równe dwa).

Dwa nulle są sobie równe.

null jest zamieniany na „null” jeśli wyrażenie jest traktowane jako String (na przykład przy dodawaniu Stringów).

Nie można porównywać referencji różnych typów (obiektowych).

Źródła:
„OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam 1Z0-808” Jeanne Boyarsky, Scott Selikoff
„JA+ V8 for Oracle Certified Associate – Java SE8 Programmer I” http://enthuware.com

OCA Struktura klasy

Struktura klasy

Pakiety

Nie trzeba importować pakietu java.lang oraz klas z aktualnego pakietu. Wildcard import dotyczy tylko konkretnych klas nie paczek. Dozwolony jest tylko jeden symbol wildcard na import – musi być na końcu. Nie można importować metod instancyjnych. Import konkretny ma priorytet nad wildcard i nie powoduje błędu kompilacji.

Nie można zaimportować domyślnego pakietu.

Rozpoczęcie nazwy pakietu od java lub javax skutkuje błędem SecurityException w czasie uruchomienia.


Zawartość klasy

Kolejność sekcji w klasie: pakiet, import, class (wymagane), pola i metody.

Zagnieżdżone komentarze blokowe powodują błąd kompilacji (konkretnie ich zamknięcie).

Klasa może być pakietowa, kilka klas może być zadeklarowanych w jednym pliku z czego maksymalnie jedna może być publiczna. Nazwa klasy publicznej musi pokrywać się z nazwą pliku.

Kolejność klas w jednym pliku nie ma znaczenia (nawet jeśli się nawzajem rozszerzają).

Kolejność inicjalizacji

  • inicjalizacja klasy bazowej
  • statyczne zmienne i bloki w kolejności deklaracji
  • instancyjne zmienne i bloki w kolejności deklaracji
  • konstruktor

Można uruchomić metodę main z klasy abstrakcyjnej.

Main musi zwracać void w innym przypadku w czasie uruchomienia będzie rzucony error.

Literał liczbowy to int, inne podstawy dla literałów to 0 – ósemkowy, 0x lub 0X – szesnastkowy, 0b lub 0B – binarny. W liczbach można dodawać _ ale nie na początku, końcu liczby ani przy kropce. Jeśli literał mieści się w zakresie jest niejawnie rzutowany na niższy np. byte.

Literał z częścią ułamkową jest typu double.

W jednej instrukcji można inicjalizować kilka zmiennych tego samego typu (typ może się pojawić tylko raz).

Wszystkie nazwy w javie muszą zaczynać się od litery lub $ lub _. W javie 9 nie można wykorzystywać samego _ jako nazwy. Nie można wykorzystywać słów kluczowych. Można wykorzystać jako nazwę nazwę wrappera (np .Integer Integer = new Integer(1);) ale nie typu prostego. Przy odwołaniach najpierw jest brana pod uwagę zmienna o nazwie jak typ a nie metody statyczne typu.

Zmienne lokalne przed odwołaniem muszą być zainicjalizowane (inaczej występuje błąd kompilacji), zmienne instancyjne i statyczne mają domyślne wartości. Jeśli zmienna lokalna jest inicjalizowana w sekcji ifa wtedy musi być też inicjalizowana w else (nie może być alternatywny if który jest negacją pierwszego warunku. Kompilator wie, że zmienna lokalna zawsze będzie zainicjalizowania w switchu bez breaków.

Źródła:
„OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam 1Z0-808” Jeanne Boyarsky, Scott Selikoff
„JA+ V8 for Oracle Certified Associate – Java SE8 Programmer I” http://enthuware.com

Git Internals

Niezmienne obiekty

Baza danych gita to mapa której kluczem są hashe SHA-1. Jest przechowywana jako katalogi w .git/objects/, nazwa katalogu to dwa pierwsze znaki hasha (wewnątrz są wszystkie obiekty których hash tak się zaczyna), obiekty to pliki binarne spakowane zlibem z dołączonym nagłówkiem. Nazwa obiektu to pozostałe 38 znaków skrótu.

Blob

Obiekt zawierający zawartość pliku, nie zawiera jego nazwy, ścieżki ani uprawnień. Dlatego dwa pliki o innych nazwach a tej samej zawartości są zapisywane w gicie jako jeden obiekt. Obiekty zapisane są w formacie typObiektu wielkośćObiektu\0 daneBinarne. Hash jest wyliczany z całego obiektu wraz z tym nagłówkiem.
Składnia commit:ścieżkaDoPliku umożliwia odwołanie się do bloba.

Tree

Drzewo zawiera nagłówek i wpisy o strukturze:
rodzajeWpisów typObiektu hash nazwaPliku

Rodzaje wpisów w drzewie

040000 – drzewo
100644 – normalny
100755 – uprawnienia do wykonywania
120000 – dowiązanie symboliczne

Umożliwia zapisanie informacji o nazwach i typach plików oraz o strukturze katalogów. Git ignoruje puste foldery.
Składania commit^{tree} umożliwia odwołanie się do drzewa przypisanego do commita

Commit

commit 226tree 6d3a746eeb961ebb0c908653d3f1097b165de352
parent 9eeb2b181261665d6b32d8d3fd242d82d1369454
author Karol Nowak <poczta@karolnowak.net> 1503008723 +0200
committer Karol Nowak <poczta@karolnowak.net> 1503008723 +0200

Commit zawiera nagłówek, wskaźnik do drzewa i rodzica (lub rodziców dla commitu mergującego), autora i commitującego wraz z timestampem. Następnie po pustej linii jest treść commita. Autor i commitujący to różne osoby jeśli zmiany są przesłane w formie diffa (np mailem) do osoby zarządzającej repozytorium która commituje te zmiany (zarówno wysyłanie diffa mailem jak i aplikowanie go ma w gicie oddzielne komendy).

Tag

Utworzony przez git tag -a (annotated tag) to oddzielny typ obiektu w przeciwieństwie do lekkiego taga który podobnie jak branch jest tylko wskaźnikiem do commita.

tag 156object 4fd5d510efb8184fb76ad7c7064c8a78083f2c4a
type commit
tag nazwaTaga
tagger Karol Nowak <poczta@karolnowak.net> 1503057924 +0200

Treść taga

Tag zawiera nagłówek, wskaźnik do taggowanego obiektu typ taggowanego obiektu, osobę tworzącą taga i treść. Typem może być dowolny obiekt – można otagować taga.


Zmienne obiekty

Branch

Plik w .git/refs/heads/ o zawartości w postaci hasha commita. Commit to najnowszy commit na tym branchu.

HEAD

Wskaźnik na wskaźnik.
We wcześniejszych wersjach gita HEAD to było dowiązanie symboliczne do pliku opisującego brancha. Ze względu na przenośność teraz wykorzystywane są symbolic-ref które są względną ścieżką do brancha (względną do folderu .git ale nie może wskazywać nic poza folderem /refs).
git symbolic-ref HEAD wyświetli gdzie wskazuje HEAD
git symbolic-ref HEAD refs/heads/test zaktualizuje wartość HEADa parametrem

Index

Inaczej staging area lub cache. Umożliwia wybór zmian które mają się znaleźć w następnym commicie.

Working directory

Pliki przechowywane w drzewie aktualnego brancha.

Logs

Pliki wykorzystywane przez reflog, zawierają wszystkie zmiany HEADa.

Paczki i delty

Git wyznacza delty (diffy) między wersjami plików. Ale robi to w innych momentach niż SVN.

Garbage collector

Delty są liczone przez garbage collectora który uruchomi się jeśli ilość obiektów przekroczy 7000 lub ilość paczek przekroczy 50, obie wartości są konfigurowalne. GC może być też uruchomiony ręcznie przez git gc. GC tworzy dwa rodzaje obiektów paczki i indeksy (idx). Paczki to zbiory obiektów, często różnych wersji tego samego pliku (ale nie tylko). Git rozpoznaje, że obiekty to różne wersje tego samego pliku na podstawie nazwy i zawartości. W paczce znajduje się najnowsza wersja pliku oraz delty do odtworzenia starszych wersji. Indeks zawiera przesunięcia do poszczególnych obiektów.
W folderze .git powstaje plik packed-refs który zawiera informację które referencje trafiły do paczki (z .git/refs).
git verify-pack -v paczka wyświetla listę wszystkich obiektów wewnątrz paczki, jako argument przyjmuje paczkę lub indeks.

Komunikacja z serwerem

Delty są liczone także podczas komunikacji z serwerem (za pomocą git smart protocol).

Upload

Po stronie serwera proces receive-pack przesyła listę wszystkich obiektów które posiada procesowi klienta send-pack. Send-pack sprawdza jakie obiekty są w bazie. Tworzy paczkę zawierającą obiekty których nie ma na serwerze i ją przesyła.

Download

Analogicznie do powyższego, nazwy procesów to fetch-pack i upload-pack.


Inne przydatne komendy

git hash-object plik zwraca hasha podanego pliku
-w zapisuje ten obiekt w bazie gita
--stdin pobiera obiekt jako tekst ze standardowego wejścia zamiast z pliku

git cat-file bardziej szczegółowe git show
-t wyświetli typ obiektu
-p rozpozna typ obiektu i odpowiednio go wyświetli
-s zwróci wielkość pliku

git ls-tree jeśli argumentem jest commit i zawiera drzewo to je wyświetla, cat-file wyświetla commit (ale jeśli argumentem jest drzewo wtedy je wyświetli)
-r wyświetla drzewa rekurencyjnie

cat plik | zlib-flate -uncompress pozwala podejrzeć pełną zawartość obiektu (z nagłówkiem)

git fsck sprawdza integralność bazy danych, wyświetla informację o obiektach na które nic nie wskazuje

git prune umożliwia usunięcie takich obiektów
-n pokaże co będzie usunięte

git count-objects wyświetli informacje o obiektach w bazie
-vH wyświetli więcej szczegółów i zmieni jednostki

git rev-list log który pokazuje tylko hashe commitów

Źródła:
„Pro Git” 2nd ed. Scott Chacon, Ben Straub
„Git Internals”Scott Chacon

Git edycja

Git fetch

git fetch -all ściąga informacje o wszystkich branchach

git fetch remote branchZrodlowy:branchDocelowy merguje (tylko fast forward) bez konieczności przełączania się na te branche jako remote można użyć . (lokalne repozytorium)
-x usuwa też ignorowane pliki


Git clean

git clean -n wyświetla co będzie usunięte
-i tryb interaktywny
git clean nieodwracalnieusuwa wszystkie nie śledzone pliki, odwracalnie można to zrobić przez git stash --all ale zapisywane są też śledzone pliki, przeważnie wymaga modyfikatorów -fd


Git checkout

git checkout -b nazwaBrancha tworzy nowego brancha i przechodzi na niego
-B nadpisuje brancha jeśli istniał

git checkout - przełącza się na poprzedniego brancha
to skrót od git checkout @{-1} inne wartości są dozwolone

git checkout -m lub -- merge robi merga na working area (bez commita)

git checkout --ours -- plik lub -- theirs wybór jednej ze stron przy konflikcie

git checkout A...B przełącza się na ostatni wspólny commit z tych branchy

git checkout plik przywraca plik do postaci zapisanej w commicie, może być trzeba poprzedzić plik przez-- plik
git checkout '*.java' przywraca wszystkie pliki .java do postaci zapisanej w ostatnim commicie


Git reset

reset przesuwa HEADa w obrębie brancha, checkout zmienia brancha, oba obsługują --patch do operowania na fragmentach plików
git reset --soft cofa HEAD (czyli commit)
-- mixed (domyslny) cofa HEAD i index (czyli cofa commit i add)
-- hard cofa heada, index i working area (czyli commit, add i edycje)
podając plik jako argument resetu jest on przywracany do zawartości w czasie commitu (podanego jako argument lub HEAD), sam HEAD się nie zmienia
git checkout [branch]--file == git reset [branch] --hard file


Git revert

git revert -m 1 HEAD cofa ostatni commit (i wskazuje ktory rodzic obowiazuje, przy commitach mergujacych) 1 to branch docelowy 2 mergowany
robi problemy w przypadku chęci wprowadzenia cofniętych zmian w innym branchu, rozwiazanie to revert commitu ktory revertował


Git add

git add -A dodaje do indeksu wszystko
git add . dodaje nowe i zmodyfikowane bez usuniętych
git add -u dodaje zmodyfikowane i usunięte bez nowych

git add -i dodaje interaktywnie

git add -p lub --patch umożliwia dodawanie fragmentów plików

Jeśli * przy dodawaniu jest poprzedzone \ wtedy dodawana jest też zawartość podkatalogów

git rm oraz git mv robią to samo co Unixowe odpowiedniki plus dodanie do indeksu


Git commit

git commit -a dodaje do indeksu wszystkie śledzone pliki

git commit --amend „dokleja” zawartość indeksu do ostatniego commitu, można zmodyfikować wiadomość przez -m

git commit --interactivetryb interaktywny, nie ma krótszej wersji i


Git stash

git stash dodaje do stasha tylko śledzone pliki, jest równoważne z git stash save
git stash -include-untracked lub -u dodaje też nieśledzone
git stash --all dodaje też ignorowane

git stash show daje mniej informacji niż git show

git stash apply stash@{2} wprowadza zmiany z drugiego stasha

drop usuwa stasha
popwprowadza zmiany i usuwa
branchwprowadza zmiany i usuwa


Git merge

git merge co doCzego

git merge --no-commit dodaje do indeksu i nie commituje

git merge master @{upstream} lub @{u} zastępuje to nazwę brancha zdalnego (origin/master)

git merge --abort

git merge -s ours lub theirs narzuca strategię mergowania

git merge-base szuka wspólnego przodka dwóch lub więcej commitów, przy trzech argumentach szuka przodka pierwszego oraz commita mergującego drugi i trzeci, jeśli ma nie brać pod uwagę commita mergującego trzeba dodać parametr --octopus


Git rebase

git rebase master server „dokleja” master do serwera

git pull --rebase zmiana domyślnego działania pulla

git rebase -i pozwala modyfikować każdy z commitów
git rebase --skip pomija problematyczny commit
git rebase --abort cofa rebase

git rebase --onto podstawa doPominiecia docelowy dokleja do podstawy commity z docelowego (który jest odbity od pominiętego doPominięcia)

Źródła:
„Pro Git” 2nd ed. Scott Chacon, Ben Straub
Dokumentacja gita

Git przeglądanie

Git log

git log -p -2
pokazuje zmiany wprowadzone przez dwa ostatnie commity
-- decorate dodaje informację o branchach

git log --since=2.years.1month.4weeks.1hour
„s” na końcu okresu nie ma znaczenia

git log --since 2017-06-26 --until 2017-06-30
since = after, until = before

git log --author "Karol Nowak"

git log --graph

git log -S ErrorMappingService
szuka commita który ma w diffie podany tekst

git log -L
git blame od innej strony
składnia start,end:plik bez spacji
start i end to numer albo regex w postaci /regex/
obowiązuje basic regexp (znaki specjalne muszą być poprzedzone \ nie działa alternatywa |

git log -L '/)\{2,3\}/',100:plik
śledzi kod od pierwszego wystąpienia podwójnego nawiasu zamykającego do setnej linii
git log --no-merges
analogicznie z --merges

git log -p -m
pokazuje zmiany wprowadzone w commitach mergujących

git log --grep "regex"
wyszukuje w wiadomościach commitów, może występować wiele razy
--all-match wiadomość musi spełniać wszystkie regexy
-i ignoruje wielkość znaków
-E wykorzystuje extended regexp

git log -g reflog sformatowany jak log
git reflog reflog śledzi każdą zmianę HEADa

git log --pretty=styl
style to:oneline (ma oddzielna komendę --oneline), short, medium (domyślny), full, fuller, email, raw, format (ustawiany ręcznie)


Zakresy commitów i odwołania do rodzica

git log branchOdejmowanyA..branchOdKtoregoOdejmujeB
nienaturalna kolejność
git log ^A B
bez kropek kolejność nie ma znaczenia
git log B --not A
wszystkie trzy poprzednie przykłady pokazują commity które są na branchu B i nie ma ich na A

git log A B ^C
wykorzystując ^ lub --not można porównywać więcej niż 2 commity
-- not odwraca działanie ^ po prawej

git log A...B
wyświetla commity które są tylko na jednym z tych dwóch branchy

git branch --no-merged commit lub --merged wyświetla tylko branche których ostatnie commity są osiągalne z podanego commita (musi być na końcu, domyślnie HEAD)

Przy obu notacjach z kropkami nie wpisanie prawej strony porównuje z HEADem

git log --left-right master...branch pokazuje który commit jest na którym branchu (nie działa dla ..), --chery-pick ignoruje cherry pickowane commity -- cherry-mark oznacza je

git log HEAD^ pokazuje rodzica aktualnego commita
git log HEAD^2  pokazuje drugiego rodzica(przy mergu)
git log HEAD~  pokazuje rodzica aktualnego commita
git log HEAD~3 pokazuje rodzica rodzica rodzica aktualnego commita
git log HEAD^^^ jak wyżej

^ przed referencją to negacja, po referencji to odwołanie do rodzica


git diff

git diff --staged wyświetla różnicę w plikach dodanych do indexu
--cached robi to samo

git diff -U10 pokazuje 10 linii otaczających rożnicę

git diff --stat --shortstat --dirstat

git diff --check sprawdza czy zmiana nie wprowadza zbędnych białych znaków

git diff w czasie konfliktu wyświetla tylko pliki które mają konflikty
po rozwiązaniu konfliktu można użyć parametrów -1 -2 -3 lub ich dłuższych odpowiedników --base, --ours, --theirs do wyświetlenia różnicy aktualnego stanu w stosunku do różnych stron zaangażowanych w merge


git grep

Działa jak linuksowy grep ale umożliwia przeszukiwanie repozytorium we wcześniejszym stanie bez checkoutu. Przeszukuje tylko pliki śledzone przez gita. Pusty łancuch dopasowuje wszystkie linie.

git grep regex HEAD^
-E --extended-regexp umożliwia wpisywanie regexu bez konieczności poprzedzania znaków specjalnych \ zamiast git grep ')\{2,\} można wpisać git grep -E '){2,}' (poprzednia wersja również działa)

git grep -n regex zwraca numery linii, parametry muszą być przed regexem
-count zwraca ilość pasujących linii na plik
-p próbuje wskazać nazwę funkcji w której znajduje się pasująca linia
--break wstawia pustą linię miedzy plikami
--headinginformacje o pliku poprzedzają dopasowania które są wypisane w nowych liniach


Pozostałe

git status -s pokazuje krótki opis stanu repozytorium

git shortlog podsumowuje informacje z git log
-s liczy commity poszczególnych autorów

git show gitowy toString()
wpisane bez parametrów implikuje HEAD jako parametr i pokazuje zmiany wprowadzone w ostatnim commicie

git show HEAD@{2.months} wykorzystuje reflog do pokazania stanu sprzed dwóch miesięcy

git blame -L 12,22 plik pokazuje git blame dla linijek od 12 do 22
jeśli przed hashem w git blame jest ^ to znaczy ze ta linijka nie zmieniła się od początku istnienia pliku
-C próbuje wykryć przenoszenie kodu żeby wskazać autora a nie przenoszącego raz wpisany parametr sprawdza czy kod nie jest skopiowany przeszukując tylko pliki z tego commitu, podany dwa razy szuka też w commicie tworzącym plik, podany trzy razy szuka wszędzie

git bisect start rozpoczyna bisecta
bad commit oznacza commit jako zły
good analogicznie
git bisect start złyCommit dobryCommit1 dobryCommit2 podanie dodatkowych informacji na starcie
po odnalezieniu szukanego commita trzeba wywolac git bisect reset zeby przywrocic HEADa tam gdzie ma byc

Źródła:
„Pro Git” 2nd ed. Scott Chacon, Ben Straub
Dokumentacja gita