Sự khác biệt giữa ĐẦU ^ và ĐẦU ~ trong Git là gì?


756

Khi tôi chỉ định một đối tượng cam kết tổ tiên trong Git, tôi bị nhầm lẫn giữa HEAD^HEAD~.

Cả hai đều có phiên bản "được đánh số" như HEAD^3HEAD~2.

Chúng có vẻ rất giống hoặc giống với tôi, nhưng có sự khác biệt nào giữa dấu ngã và dấu mũ không?


64
Thật tệ khi dán liên kết, tôi biết nhưng đây là lời giải thích tốt nhất tôi tìm thấy và có hình ảnh trong đó. paulboxley.com/blog/2011/06/git-caret-and-tilde
igor

4
Liên kết đặc biệt xấu khi chúng bị hỏng. Đó là lý do tại sao an toàn hơn để trả lời câu hỏi giúp ngăn chặn điều này vì khả năng sao chép dán một số giải thích :)
Samuel

Câu trả lời:


763

Quy tắc của ngón tay cái

  • Sử dụng ~hầu hết thời gian - để quay lại một số thế hệ, thường là những gì bạn muốn
  • Sử dụng ^trên các cam kết hợp nhất - bởi vì họ có hai hoặc nhiều cha mẹ (ngay lập tức)

Ghi nhớ:

  • Tilde ~gần như tuyến tính về ngoại hình và muốn đi lùi theo đường thẳng
  • Caret ^gợi ý một đoạn thú vị của một cái cây hoặc ngã ba đường

Dấu ngã

Phần chỉ định bản sửa đổi Phần của phần cứng của git rev-parsetài liệu định nghĩa ~

<rev>~<n>, ví dụ:master~3
Hậu tố ~<n>cho tham số sửa đổi có nghĩa là đối tượng cam kết là tổ tiên thế hệ thứ n của đối tượng cam kết được đặt tên, chỉ theo sau cha mẹ đầu tiên. Ví dụ, tương đương với đó là tương đương với ...<rev>~3<rev>^^^<rev>^1^1^1

Bạn có thể nhận được cho cha mẹ của bất kỳ cam kết, không chỉ HEAD. Bạn cũng có thể di chuyển trở lại qua các thế hệ: ví dụ: master~2có nghĩa là ông bà của đỉnh của nhánh chính, ưu tiên cha mẹ đầu tiên trên các cam kết hợp nhất.

Caret

Lịch sử Git là phi tuyến: biểu đồ chu kỳ có hướng (DAG) hoặc cây. Đối với một cam kết chỉ có một cha mẹ, rev~rev^có nghĩa là điều tương tự. Bộ chọn caret trở nên hữu ích với các cam kết hợp nhất vì mỗi người là con của hai hoặc nhiều cha mẹ - và ngôn ngữ chủng được mượn từ sinh học.

HEAD^có nghĩa là cha mẹ trực tiếp đầu tiên của đầu của chi nhánh hiện tại. HEAD^là viết tắt của HEAD^1, và bạn cũng có thể giải quyết HEAD^2và như vậy là phù hợp. Phần tương tự của git rev-parsetài liệu định nghĩa nó là

<rev>^, Ví dụ HEAD^ ,v1.5.1^0
một hậu tố ^để một tham số sửa đổi có nghĩa là phụ huynh đầu tiên về điều đó cam kết đối tượng. ^<n>có nghĩa là cha mẹ thứ n ([ ví dụ ] tương đương với ). Như một quy tắc đặc biệt, có nghĩa là bản thân cam kết và được sử dụng khi<rev>^<rev>^1<rev>^0<rev> là tên đối tượng của đối tượng thẻ tham chiếu đến đối tượng cam kết.

Ví dụ

Các bộ xác định hoặc bộ chọn này có thể được xâu chuỗi tùy ý, ví dụ , topic~3^2trong tiếng Anh là cha mẹ thứ hai của cam kết hợp nhất là ông bà (ba thế hệ trở lại) của đầu hiện tại của chi nhánhtopic .

Phần nói trên của git rev-parsetài liệu theo dõi nhiều đường dẫn thông qua lịch sử git nổi tiếng. Thời gian thường chảy xuống. Các cam kết D, F, B và A là các cam kết hợp nhất.

Đây là một minh họa, bởi Jon Loeliger. Cả hai nút cam kết B và C là cha mẹ của nút cam kết A. Các cam kết cha mẹ được sắp xếp từ trái sang phải.

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A

A =      = A^0
B = A^   = A^1     = A~1
C = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

Chạy mã dưới đây để tạo một kho git có lịch sử phù hợp với hình minh họa được trích dẫn.

#! /usr/bin/env perl

use strict;
use warnings;
use subs qw/ postorder /;
use File::Temp qw/ mkdtemp /;

my %sha1;
my %parents = (
  A => [ qw/ B C /               ],
  B => [ qw/     D E F /         ],
  C => [ qw/         F /         ],
  D => [ qw/           G H /     ],
  F => [ qw/               I J / ],
);

sub postorder {
  my($root,$hash) = @_;
  my @parents = @{ $parents{$root} || [] };
  postorder($_, $hash) for @parents;
  return if $sha1{$root};
  @parents = map "-p $sha1{$_}", @parents;
  chomp($sha1{$root} = `git commit-tree @parents -m "$root" $hash`);
  die "$0: git commit-tree failed" if $?;
  system("git tag -a -m '$sha1{$root}' '$root' '$sha1{$root}'") == 0 or die "$0: git tag failed";
}

$0 =~ s!^.*/!!;  # / fix Stack Overflow highlighting
my $repo = mkdtemp "repoXXXXXXXX";
chdir $repo or die "$0: chdir: $!";
system("git init") == 0               or die "$0: git init failed";
chomp(my $tree = `git write-tree`);      die "$0: git write-tree failed" if $?;

postorder 'A', $tree;
system "git update-ref HEAD   $sha1{A}"; die "$0: git update-ref failed" if $?;
system "git update-ref master $sha1{A}"; die "$0: git update-ref failed" if $?;

# for browsing history - http://blog.kfish.org/2010/04/git-lola.html
system "git config alias.lol  'log --graph --decorate --pretty=oneline --abbrev-commit'";
system "git config alias.lola 'log --graph --decorate --pretty=oneline --abbrev-commit --all'";

Nó chỉ thêm bí danh trong repo ném mới chỉ cho git lolgit lola vì vậy bạn có thể xem lịch sử như trong

$ git lol
*   29392c8 (HEAD -> master, tag: A) A
|\
| * a1ef6fd (tag: C) C
| |
|  \
*-. \   8ae20e9 (tag: B) B
|\ \ \
| | |/
| | *   03160db (tag: F) F
| | |\
| | | * 9df28cb (tag: J) J
| | * 2afd329 (tag: I) I
| * a77cb1f (tag: E) E
*   cd75703 (tag: D) D
|\
| * 3043d25 (tag: H) H
* 4ab0473 (tag: G) G

Lưu ý rằng trên máy của bạn, tên đối tượng SHA-1 sẽ khác với các tên trên, nhưng các thẻ cho phép bạn giải quyết các cam kết theo tên và kiểm tra sự hiểu biết của bạn.

$ git log -1 --format=%f $(git rev-parse A^)
B
$ git log -1 --format=%f $(git rev-parse A~^3~)
I
$ git log -1 --format=%f $(git rev-parse A^2~)
F

Bản sửa đổi chỉ định của người dùng trong git rev-parsetài liệu có đầy đủ thông tin tuyệt vời và đáng để đọc. Xem thêm Công cụ Git - Lựa chọn sửa đổi từ cuốn sách Pro Git .

Thứ tự cam kết của phụ huynh

Cam kết 89e4fcb0dd từ lịch sử của git là một cam kết hợp nhất, như git show 89e4fcb0ddbiểu thị với dòng tiêu đề Hợp nhất hiển thị tên đối tượng của tổ tiên ngay lập tức.

commit 89e4fcb0dd01b42e82b8f27f9a575111a26844df
Merge: c670b1f876 649bf3a42f b67d40adbb
Author: Junio C Hamano <gitster@pobox.com>
Date:   Mon Oct 29 10:15:31 2018 +0900

    Merge branches 'bp/reset-quiet' and 'js/mingw-http-ssl' into nd/config-split […]

Chúng tôi có thể xác nhận việc đặt hàng bằng cách yêu cầu git rev-parsehiển thị cha mẹ ngay lập tức của 89e4fcb0dd.

$ git rev-parse 89e4fcb0dd^1 89e4fcb0dd^2 89e4fcb0dd^3
c670b1f876521c9f7cd40184bf7ed05aad843433
649bf3a42f344e71b1b5a7f562576f911a1f7423
b67d40adbbaf4f5c4898001bf062a9fd67e43368

Truy vấn cha mẹ thứ tư không tồn tại dẫn đến một lỗi.

$ git rev-parse 89e4fcb0dd^4
89e4fcb0dd^4
fatal: ambiguous argument '89e4fcb0dd^4': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Nếu bạn chỉ muốn trích xuất cha mẹ, hãy sử dụng định dạng đẹp %P cho toàn bộ băm

$ git log -1 --pretty=%P 89e4fcb0dd
c670b1f876521c9f7cd40184bf7ed05aad843433 649bf3a42f344e71b1b5a7f562576f911a1f7423 b67d40adbbaf4f5c4898001bf062a9fd67e43368

hoặc %pcho cha mẹ viết tắt.

$ git log -1 --pretty=%p 89e4fcb0dd
c670b1f876 649bf3a42f b67d40adbb

có vẻ như ^ có thể xử lý tất cả các trường hợp và người ta có thể tự hỏi tại sao ~ xuất hiện ở nơi đầu tiên. Tại sao không chỉ nhớ làm thế nào ^ hoạt động?
Sbu

điều này thật khó hiểu vẫn còn ... giả sử G là TRỤ, vì vậy nếu tôi làm TRƯỚC ^ thì đó sẽ là D ... phải không?
Patoshi パ ト シ

12
@duckx đồ thị thực sự đi từ trên xuống dưới, vì vậy A là cam kết gần đây nhất và G là một trong những cam kết cũ nhất. Con đường từ G đến D là tiến, không lùi, từ những gì tôi có thể nói.
tỷ lệ vàng

@SimonBudin Tôi đoán, nó không thuận tiện để sử dụng ^^^^^^^thay vì ~7, phải không? Đó là lý do tại sao ~hữu ích
YakovL 17/12/18

1
@AdityaVikasDevarapalli Điều đó sẽ tốt như câu hỏi của chính nó.
Greg Bacon

340

Sự khác biệt giữa HEAD^HEAD~được mô tả rõ bằng hình minh họa (của Jon Loeliger) được tìm thấy trên http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html .

Tài liệu này có thể hơi mơ hồ đối với người mới bắt đầu nên tôi đã sao chép hình minh họa dưới đây:

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A
A =      = A^0
B = A^   = A^1     = A~1
C = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

12
Chỉ một câu hỏi. Làm thế nào có thể cho một cam kết có nhiều hơn hai cha mẹ? (Xem B - đó là cha mẹ của D, E và F) Tôi tưởng tượng rằng cách duy nhất một cam kết có thể có hai cha mẹ là khi đó là một cam kết hợp nhất ... nhưng làm thế nào bạn có thể hợp nhất 3 lần cam kết?
tsikov

Nếu tôi không nhầm, điều này có thể rõ ràng, nhưng tôi nghĩ nên xác định rằng CHÍNH ~ theo nhánh hiện tại (như Diego Dias được đề cập dưới đây).
Fibono

2
Ngoài ra , F = A^2^.
Mateen Ulhaq

2
Vì vậy, ^ == ^1 == LEFTMOST PARENT, ^2 == SECOND LEFTMOST PARENTvà vân vân. Và ~ == ~1 == LEFTMOST PARENT, ~2 == LEFTMOST PARENTS LEFTMOST PARENT == LEFTMOST GRANDPARENT. Bằng cách mở rộng,~2^2 == LEFTMOST GRANDPARENTS SECOND LEFTMOST PARENT
Alexander Torstling

1
@AlexanderTorstling điều này rất hữu ích cho tôi. Tuy nhiên, trái và phải có nghĩa gì ở đây?
đa

287

Cả hai ~và đều ^đề cập đến cha mẹ của cam kết ( ~~^^cả hai đều đề cập đến cam kết của ông bà, v.v.) Nhưng chúng khác nhau về ý nghĩa khi chúng được sử dụng với các số:

  • ~2có nghĩa là tăng hai cấp trong cấu trúc phân cấp , thông qua cha mẹ đầu tiên nếu một cam kết có nhiều hơn một cha mẹ

  • ^2có nghĩa là cha mẹ thứ hai nơi một cam kết có nhiều hơn một cha mẹ (nghĩa là vì đó là một sự hợp nhất)

Chúng có thể được kết hợp, vì vậy HEAD~2^3có nghĩa là HEADcam kết cha mẹ thứ ba của ông bà.


2
Đọc điều này theo sau là hình ảnh từ stackoverflow.com/questions/2221658/ cảm thấy hoàn hảo.
kunigami

23
Đây phải là câu trả lời được chấp nhận, cô đọng và hữu ích hơn nhiều so với những câu hỏi khác.
RichVel

3
Câu trả lời này khiến tôi phân biệt giữa dấu mũ / dấu ngã không có số và với số! Tôi nghĩ ^^giống như ^2vậy nhưng không phải.
Alexander Derck

278

Theo quan điểm của tôi...

nhập mô tả hình ảnh ở đây


Và làm thế nào H=A~2^2không H=A~2^1?
Mohammad Faisal

3
Nếu tôi figured it out một cách chính xác, các cam kết A, B, D, Gđang trên cùng một chi nhánh và cam kết Dlà một kết hợp của GH, do đó có hai bố mẹ. Vì vậy, commit ( H) từ nhánh khác được tham chiếu bởi ^2.
Mohammad Faisal

62

Đây là một lời giải thích rất hay được lấy nguyên văn từ http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde :

ref~là viết tắt cho ref~1và có nghĩa là cha mẹ đầu tiên của cam kết. ref~2có nghĩa là cha mẹ đầu tiên của cam kết. ref~3nghĩa là cha mẹ đầu tiên của cha mẹ đầu tiên của cam kết. Và như thế.

ref^là viết tắt cho ref^1và có nghĩa là cha mẹ đầu tiên của cam kết. Nhưng nơi hai khác nhau làref^2 có nghĩa là cha mẹ thứ hai của cam kết (hãy nhớ rằng, các cam kết có thể có hai cha mẹ khi chúng là hợp nhất).

Các toán tử ^~có thể được kết hợp.

nhập mô tả hình ảnh ở đây


5
Cảm ơn bạn đã thực sự giải thích sự khác biệt hơn là đăng một loạt các ví dụ.
Kirk Broadhurst

32

Các ^<n>định dạng cho phép bạn chọn phụ huynh thứ n của các cam kết (có liên quan trong hòa trộn). Các ~<n>định dạng cho phép bạn chọn thứ n tổ tiên cam kết, luôn luôn sau khi cha mẹ đầu tiên. Xem tài liệu của git-rev-parse để biết một số ví dụ.


21

Điều đáng chú ý là git cũng có một cú pháp để theo dõi "từ nơi bạn đến" / "muốn quay trở lại ngay bây giờ" - ví dụ, HEAD@{1}sẽ tham chiếu địa điểm từ nơi bạn nhảy đến vị trí cam kết mới.

Về cơ bản HEAD@{}các biến nắm bắt lịch sử của chuyển động CHÍNH, và bạn có thể quyết định sử dụng một đầu cụ thể bằng cách xem xét các bản cập nhật của git bằng lệnh git reflog.

Thí dụ:

0aee51f HEAD@{0}: reset: moving to HEAD@{5}
290e035 HEAD@{1}: reset: moving to HEAD@{7}
0aee51f HEAD@{2}: reset: moving to HEAD@{3}
290e035 HEAD@{3}: reset: moving to HEAD@{3}
9e77426 HEAD@{4}: reset: moving to HEAD@{3}
290e035 HEAD@{5}: reset: moving to HEAD@{3}
0aee51f HEAD@{6}: reset: moving to HEAD@{3}
290e035 HEAD@{7}: reset: moving to HEAD@{3}
9e77426 HEAD@{8}: reset: moving to HEAD@{3}
290e035 HEAD@{9}: reset: moving to HEAD@{1}
0aee51f HEAD@{10}: reset: moving to HEAD@{4}
290e035 HEAD@{11}: reset: moving to HEAD^
9e77426 HEAD@{12}: reset: moving to HEAD^
eb48179 HEAD@{13}: reset: moving to HEAD~
f916d93 HEAD@{14}: reset: moving to HEAD~
0aee51f HEAD@{15}: reset: moving to HEAD@{5}
f19fd9b HEAD@{16}: reset: moving to HEAD~1
290e035 HEAD@{17}: reset: moving to HEAD~2
eb48179 HEAD@{18}: reset: moving to HEAD~2
0aee51f HEAD@{19}: reset: moving to HEAD@{5}
eb48179 HEAD@{20}: reset: moving to HEAD~2
0aee51f HEAD@{21}: reset: moving to HEAD@{1}
f916d93 HEAD@{22}: reset: moving to HEAD@{1}
0aee51f HEAD@{23}: reset: moving to HEAD@{1}
f916d93 HEAD@{24}: reset: moving to HEAD^
0aee51f HEAD@{25}: commit (amend): 3rd commmit
35a7332 HEAD@{26}: checkout: moving from temp2_new_br to temp2_new_br
35a7332 HEAD@{27}: commit (amend): 3rd commmit
72c0be8 HEAD@{28}: commit (amend): 3rd commmit

Một ví dụ có thể là tôi đã thực hiện các cam kết cục bộ a-> b-> c-> d và sau đó tôi quay lại loại bỏ 2 cam kết để kiểm tra mã của mình - git reset HEAD~2- và sau đó tôi muốn chuyển ĐẦU của tôi trở lại d - git reset HEAD@{1}.


17

Đơn giản :

  • ~ chỉ định tổ tiên
  • ^ chỉ định cha mẹ

Bạn có thể chỉ định một hoặc nhiều chi nhánh khi hợp nhất. Sau đó, một cam kết có hai hoặc nhiều cha mẹ và sau đó^ là hữu ích để chỉ cha mẹ.

Giả sử bạn đang ở trên nhánh A và bạn có thêm hai chi nhánh: BC .

Trên mỗi nhánh, ba cam kết cuối cùng là:

  • A : A1 , A2 , A3
  • B : B1 , B2 , B3
  • C : C1 , C3 , C3

Nếu bây giờ trên nhánh A, bạn thực hiện lệnh:

git merge B C

sau đó bạn kết hợp ba nhánh lại với nhau (ở đây cam kết hợp nhất của bạn có ba cha mẹ)

~ chỉ ra tổ tiên thứ n trong nhánh đầu tiên, vì vậy

  • HEAD~chỉ ra A3
  • HEAD~2chỉ ra A2
  • HEAD~3chỉ ra A1

^ chỉ ra cha mẹ thứ n, vì vậy

  • HEAD^chỉ ra A3
  • HEAD^2chỉ ra B3
  • HEAD^3chỉ ra C3

Việc sử dụng tiếp theo ~hoặc ^bên cạnh nhau là trong bối cảnh của cam kết được chỉ định bởi các nhân vật trước đó.

Thông báo 1 :

  • HEAD~3luôn luôn bằng: HEAD~~~và với: HEAD^^^(mọi chỉ ra A1 ),

        và nói chung :

  • HEAD~nluôn luôn bằng: HEAD~...~( n lần ~) và với: HEAD^...^( n lần ^).

Lưu ý 2 :

  • HEAD^3không giống như HEAD^^^(người đầu tiên chỉ ra C3 và lần thứ hai chỉ ra A1 ),

        và nói chung :

  • HEAD^1 giống như HEAD^ ,
  • nhưng với n > 1: HEAD^nluôn không giống với HEAD^...^( n lần ~).

15

TLD

~ là những gì bạn muốn hầu hết thời gian, nó tham chiếu các cam kết trong quá khứ cho chi nhánh hiện tại

^ tham chiếu cha mẹ (git-merge tạo cha mẹ thứ 2 trở lên)

A ~ luôn giống với A ^
A ~ ~ luôn giống với A ^^, và vì vậy
A ~ 2 không giống với A ^ 2, tuy nhiên,
vì ~ 2 là tốc ký cho ~ ~
trong khi ^ 2 thì không tốc ký cho bất cứ điều gì, nó có nghĩa là cha mẹ thứ 2


11

ĐẦU ^ ^ giống như TRƯỚC ~ 3, chọn cam kết thứ ba trước TRƯỚC

Đầu ^ 2 chỉ định đầu thứ hai trong một cam kết hợp nhất


9
  • HEAD ~ chỉ định cha mẹ đầu tiên trên một "nhánh"

  • ĐẦU ^ cho phép bạn chọn một cha mẹ cụ thể của cam kết

Một ví dụ:

Nếu bạn muốn theo một nhánh bên, bạn phải chỉ định một cái gì đó như

master~209^2~15


0

Nói một cách đơn giản, đối với cấp bậc cha mẹ đầu tiên (tổ tiên, thừa kế, dòng dõi, v.v.) Head ^ và HEAD ~ cả hai đều trỏ đến cùng một cam kết, đó là (nằm) một cha mẹ phía trên ĐẦU (cam kết).

Hơn nữa, ĐẦU ^ = ĐẦU ^ 1 = ĐẦU ~ = ĐẦU ~ 1. Nhưng ĐẦU ^^! = ĐẦU ^ 2! = ĐẦU ~ 2. Chưa đầu ^^ = ĐẦU ~ 2. Đọc tiếp.

Vượt quá mức đầu tiên của cha mẹ, mọi thứ trở nên phức tạp hơn, đặc biệt là nếu nhánh làm việc / nhánh chính đã có sự hợp nhất (từ các nhánh khác). Ngoài ra còn có vấn đề về cú pháp với dấu mũ, ĐẦU ^^ = ĐẦU ~ 2 (chúng tương đương) NHƯNG ĐẦU ^^! = ĐẦU ^ 2 (chúng hoàn toàn là hai thứ khác nhau).

Mỗi / dấu mũ đề cập đến cha mẹ đầu tiên của ĐẦU, đó là lý do tại sao các chuỗi được nối với nhau tương đương với biểu thức dấu ngã, bởi vì chúng đề cập đến cha mẹ đầu tiên (cha mẹ đầu tiên), v.v., dựa trên số trên các dấu mũ được kết nối hoặc trên số theo dấu ngã (cả hai cách, cả hai đều có nghĩa giống nhau), tức là ở với cha mẹ đầu tiên và đi lên x thế hệ.

ĐẦU ~ 2 (hoặc ĐẦU ^^) đề cập đến cam kết có hai cấp độ tổ tiên lên / trên mức cam kết hiện tại (ĐẦU) trong cấu trúc phân cấp, nghĩa là cam kết ông bà của ĐẦU.

Mặt khác, ^ 2, mặt khác, KHÔNG nói đến cam kết của cha mẹ thứ hai của cha mẹ thứ nhất, mà chỉ đơn giản là cam kết của cha mẹ thứ hai. Đó là bởi vì dấu mũ có nghĩa là cha mẹ của cam kết và số sau đây biểu thị cho / cam kết cha mẹ nào được đề cập đến (cha mẹ đầu tiên, trong trường hợp khi dấu mũ không được theo sau bởi một số [vì nó là tốc ký cho số là 1, có nghĩa là cha mẹ đầu tiên]). Không giống như dấu mũ, số tiếp theo sau đó không bao hàm một cấp bậc khác lên trên, mà nó bao hàm bao nhiêu cấp độ đi ngang, vào hệ thống phân cấp, người ta cần phải đi tìm cha mẹ chính xác (cam kết). Không giống như số trong biểu thức dấu ngã, nó chỉ có một cha mẹ trong cấu trúc phân cấp, bất kể số (ngay lập tức) tiến hành dấu mũ. Thay vì hướng lên, dấu mũ '

Vì vậy, ĐẦU ^ 3 bằng với cha mẹ thứ ba của cam kết CHÍNH (KHÔNG phải là ông cố, đó là những gì CHÍNH ^^ ^ VÀ TRƯỚC ~ 3 sẽ là ...).


-1

~ điều này có nghĩa là cha mẹ.

^ nếu nó có cha mẹ của hai hoặc nhiều hơn, như hợp nhất cam kết, chúng ta có thể chọn thứ hai của cha mẹ hoặc cái khác.

vì vậy nếu chỉ một thứ như (ĐẦU ~ hoặc ĐẦU ^), thì nó cũng có kết quả tương tự .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.