Làm cách nào để tránh gõ gõ git trực khi bắt đầu mọi lệnh Git?


190

Tôi tự hỏi liệu có cách nào để tránh phải gõ từ đó gitvào đầu mỗi lệnh Git không.

Sẽ thật tuyệt nếu có một cách chỉ sử dụng gitlệnh một lần vào đầu sau khi mở dấu nhắc lệnh để vào "Chế độ Git" .

Ví dụ:

git>

Sau đó, mỗi lệnh chúng ta gõ theo mặc định được hiểu là lệnh Git.

Theo cách tương tự như cách chúng ta sử dụng trình vỏ MySQL để viết các lệnh cơ sở dữ liệu:

mysql>

Điều này sẽ giúp tôi không phải gõ githàng trăm lần một ngày.

LƯU Ý: Tôi đang sử dụng git-bash, trên Windows.


87
Đối với những người đã bỏ phiếu đóng trên cơ sở nó không có chủ đề, vui lòng đọc văn bản bạn đang nhấp vào: "Câu hỏi về phần cứng và phần mềm máy tính nói chung không có chủ đề cho Stack Overflow trừ khi chúng liên quan trực tiếp đến các công cụ được sử dụng chủ yếu cho lập trình . ". Git là một công cụ được sử dụng bởi các lập trình viên. Bằng chứng là nó có thẻ riêng trên trang này.
JBentley

5
Tại sao bạn gõ "git" rất nhiều? IDE của bạn nên có tích hợp vcs mạnh mẽ có sẵn tại một phím nhấn. Bạn có nên gõ "git pull" 50 lần một ngày hay ctrl-t ... hãy ngừng là một chiến binh dòng lệnh khi bạn không cần phải như vậy;)
vikingsteve

8
@vikingsteve Thực tế tất cả sự giúp đỡ và trí tuệ của git được đưa ra dưới dạng dòng lệnh.
Ed Randall

6
@vikingsteve Tôi đang gõ nó rất nhiều vì nó nhanh hơn. Tôi gõ ~ 100wpm, hơn nữa nếu tôi quen thuộc với các phím bấm như tôi với Git; so với việc nhấp vào GUI, nó chỉ dễ dàng hơn. IDE yêu thích của bạn có thể có phím tắt. Điều đó tốt cho bạn Tại sao tôi lại lãng phí thời gian để học chúng khi <M-Tab> git blah <CR> đã có trong bộ nhớ cơ bắp của tôi?
Vụ kiện của Quỹ Monica

3
Cần có một "câu hỏi này nên được đóng lại vì người dùng đang hỏi một câu hỏi không có ý nghĩa" - giống như tôi hiểu những gì bạn đang hỏi nhưng làm thế nào vỏ sẽ biết bạn muốn nhập "không bắt đầu bằng lệnh git "nếu thực sự có một cách để làm điều này.
dùng3728501

Câu trả lời:


190

Bạn có thể muốn thử gitsh . Từ readme của họ:

Các gitshchương trình là một vỏ tương tác cho git. Từ bên trong gitshbạn có thể đưa ra bất kỳ lệnh git nào, thậm chí sử dụng bí danh và cấu hình cục bộ của bạn.

  • Các lệnh Git có xu hướng đến trong các nhóm. Tránh gõ đi viết gitlại nhiều lần bằng cách chạy chúng trong vỏ git chuyên dụng:
sh$ gitsh
gitsh% status
gitsh% add .
gitsh% commit -m "Ship it!"
gitsh% push
gitsh% ctrl-d
sh$

Hoặc có một cái nhìn về các dự án khác được liên kết ở đó:

  • git-sh - Một vỏ bash tùy chỉnh với dấu nhắc Git, bí danh và hoàn thành.
  • gitsh - Một vỏ Git đơn giản được viết bằng Perl.
  • thay thế - Kết thúc bất kỳ chương trình nào với các tiểu ban trong REPL.

Lưu ý: Không sử dụng bản thân mình.


22
càu nhàu ... repl(1)không phải là REPL. Nó không eval hoặc in bất cứ điều gì. Nó chạy các chương trình.
Kevin

11
@Kevin Nó đọc các yêu cầu của người dùng, đánh giá yêu cầu của người dùng (bằng cách chạy một chương trình) và in kết quả đầu ra của chương trình. Đây cũng là những gì vỏ làm.
Yakk - Adam Nevraumont

2
@ Yakk-AdamNevraumont: Không, chắc chắn là nó không "in kết quả đầu ra của chương trình". Nó kết nối thiết bị xuất chuẩn của thiết bị đến thiết bị đầu cuối và sau đó chương trình sẽ in đầu ra của chính nó - ngoại trừ thiết bị xuất chuẩn của chương trình đã được nối với thiết bị đầu cuối (được kế thừa tự động qua fork()/ exec()), do đó repl(1)thậm chí không làm điều đó .
Kevin

6
@Kevin Tôi hiểu tình cảm của bạn, tuy nhiên định nghĩa chặt chẽ về REPL sẽ loại trừ hầu hết thông dịch viên REP REPL bằng các ngôn ngữ khác nhau. Chỉ bằng các ngôn ngữ chức năng thuần túy, bạn mới có thể đảm bảo rằng việc đánh giá không có tác dụng phụ, nhưng ngay cả trong Haskell, REPL, GHCi theo mặc định cũng sẽ chấp nhận IOcác hành động và thực hiện chúng bao gồm các tác dụng phụ như in ra màn hình được kết nối đầu cuối.
rẽ trái

2
@Kevin replkhông phải là REPL độc lập; nó là một phương tiện để tạo ra một hệ thống REPL trong đó replchỉ là thành phần tương tác. Như vậy có công bằng không?
Kyle Strand

116

Một lớp lót Perl sẽ làm điều này:

perl -nE 'BEGIN {print "git > "} system "git $_"; print "git > "'

Điều này sẽ thực thi bất cứ điều gì bạn gõ, tiền tố git. Và nó sẽ tiếp tục làm điều đó cho đến khi bạn đạt được ^D.


6
Điều này thực sự giống với những gì OP đang yêu cầu, và trong một gói rất nhẹ!
ruohola

2
Điều này sẽ là hoàn hảo nếu nó hoạt động với readline nhưng tiếc là nó không (không đáng ngạc nhiên vì đây hoàn toàn là một bản hack xung quanh -necờ của Perl ).
Konrad Rudolph

11
@KonradRudolphperl -MTerm::ReadLine -E '$n = Term::ReadLine -> new ("git"); while ($_ = $n -> readline ("git > ")) {system "git $_"}'

57

Đây không phải là chính xác những gì bạn yêu cầu, nhưng bạn có thể thiết lập một số bí danh shell trong ~/.bashrccác lệnh Git mà bạn sử dụng thường xuyên nhất:

alias commit='git commit'
alias checkout='git checkout'
...

Cũng lưu ý rằng bạn có thể tạo bí danh trong chính Git:

git config --global alias.ci commit
git config --global alias.co checkout
...

Điều này cho phép bạn gõ git cithay vì git commit, và như vậy.


7
Hạn chế của phương pháp này là một bí danh riêng biệt sẽ cần được tạo cho mỗi lệnh Git.
Tim Biegeleisen

22
Chỉ dành cho những người sử dụng thường xuyên nhất. Ý tôi là, bạn có thường xuyên sử dụng git hash-objecthay git interpret-trailerskhông? Tôi chỉ đưa ra điều này như một sự thay thế bởi vì theo như tôi biết, câu hỏi đang hỏi là gì không thực sự tồn tại.
Thomas

15
Ngoài cicho committôi cũng sử dụng một bí danh vỏ gcho git, điều này làm giảm hầu hết các đánh máy và cho phép tôi ở lại vỏ ưa thích của tôi.
rkta

32

Tôi là một fan hâm mộ lớn của việc sử dụng các bí danh trong ~ / .bash_profile cho GitBash của tôi. Nếu bạn đi theo phương pháp này, đây là một số mục yêu thích của tôi:

# git
alias gw='git whatchanged'
alias gg='git grep -n -C8'
alias ggi='git grep -i -n -C8'
alias gb='git branch'
alias gbd='git branch -D'
alias gba='git branch -a'
alias gc='git checkout'
alias gcp='git cherry-pick'
alias gfo='git fetch origin'
alias s='git status'
alias gmom='git merge origin/master'
alias grom='git rebase origin/master'
alias gpom='git pull origin master'
alias pplog='git log --oneline --graph --decorate'

3
cam kết ở đâu: P
qwr

14
Tôi không bao gồm commithoặc pushvì tôi muốn thêm vài giây (trong khi gõ) để chắc chắn rằng tôi sẽ không phá hủy thứ gì đó
JacobIRR

3
Cam kết và đẩy không nên phá hủy bất cứ thứ gì trừ khi bạn sử dụng lực đẩy. Nhưng tôi cố gắng sử dụng trạng thái git trước.
qwr

1
đây là những gì tôi đã làm, +1. Mặc dù tôi rất muốn thử gitsh như các câu trả lời khác đã đề cập
CoffeeTableEspresso

1
@CoffeeTableEspresso Tôi tôn trọng thực tế rằng bạn thừa nhận rằng một vài tổ hợp phím là sự khác biệt giữa lưu các bản cập nhật và phá hủy một dự án.
LogicalBranch

31

Sử dụng trình soạn thảo của bạn.

Nhập lệnh như committừ trình soạn thảo yêu thích của bạn như vs mã và hiệu quả hơn với git:

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

Hoặc gõ gitđể nhận tất cả các lệnh:

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


13
Tôi ngạc nhiên bởi tất cả những phiếu bầu này. Đây không phải là một câu trả lời khủng khiếp cho những người sử dụng IDE hỗ trợ các tính năng này.
Glen Pierce

4
Tôi nghĩ mọi người đã bỏ phiếu xuống vì không phải ai cũng sử dụng / thích VS-Code. Dù bằng cách nào, tôi nghĩ đó là một giải pháp tốt nên +1 từ tôi.
LogicalBranch

4
@LogicalBranch, mọi người thường sử dụng git từ dòng lệnh và tôi biết điều đó, nhưng sự hỗ trợ git bên trong một số trình soạn thảo tồn tại và nó đáng để thử.
prosti

1
Tôi không thích câu trả lời này vì không phải ai cũng sử dụng mã VS (cá nhân tôi không thích nó), nhưng sẽ không downvote vì đây là một giải pháp tốt cho ppl sử dụng nó.
CoffeeTableEspresso

1
@CoffeeTableEspresso, nếu bạn đang sử dụng tuyệt vời, có một plugin có tên là gitsavvy , v.v ... Hầu như mọi trình soạn thảo hiện nay đều có một số loại hỗ trợ cho git. Đây là điểm của câu trả lời, vì bạn có thể đọc "Sử dụng trình soạn thảo của mình".
prosti

26

Một người bạn của tôi đã tạo ra một kịch bản bash nhỏ để thực hiện điều này. Nó được gọi là Thay thế .

$ replify git
Initialized REPL for [git]
git> init
Initialized empty Git repository in /your/directory/here/.git/

git> remote add origin https://your-url/repo.git

git> checkout -b new-branch
Switched to a new branch 'new-branch'

git> push

6
OK, tôi đã đề cập rằng trong câu trả lời của Umur, nhưng việc sử dụng evaltrong nguồn kịch bản gốc không phải là ý tưởng tốt nhất. Nói với bạn của bạn để sử dụng while IFS= read -r -p "git> " gitcmd; do [ "x$gitcmd" != "x" ] && git "$gitcmd";donethay thế
Sergiy Kolodyazhnyy

23

Đây là một cách khác. Nó cũng không hoàn toàn như những gì được hỏi, nhưng tôi đã sử dụng nó một thời gian và nó khá đẹp. Thêm dòng sau vào ~/.bashrc:

complete -E -W git

Bây giờ, nhấn Tab tại dấu nhắc Bash trống sẽ gõ "git".


5
Lưu ý rằng nếu bạn đang sử dụng shell khác, bạn sẽ phải đặt nó vào tệp thích hợp. Ví dụ: đối với zsh, bạn sẽ đặt nó vào ~/zshrc, đối với tcsh, bạn sẽ đặt nó vào ~/tcshrc, v.v.
TheOnlyMrCat

20

Tôi biết đây là một câu trả lời rất muộn nhưng câu hỏi này thực sự gây chú ý với tôi bởi vì tôi đã phải đối phó với sự đau khổ từ loại lặp đi lặp lại này khá lâu rồi.

Tôi không chắc chắn về bạn nhưng tôi thực sự không (tôi nhắc lại KHÔNG ) muốn tạo bí danh cho mỗi gitlệnh, vì vậy thay vào đó tôi đã viết một tập lệnh python có tên NoGit để giải quyết vấn đề này:

#!/usr/bin/env python
import sys, os, signal, atexit, readline, subprocess

commands, stop, history_file = [], False, os.path.join(os.getcwd(), "git.history")

def run_commands():
  stop = True
  for cmd in commands:
    command = ["git" if not cmd.startswith("git ") else ""]
    command = [cmd] if command[0] == "" else [command[0], cmd]
    subprocess.Popen(command).communicate()
    commands = []

def signal_handler(sig, frame):
  run_commands()
  sys.exit(0)

try:
  readline.read_history_file(history_file)
  signal.signal(signal.SIGINT, signal_handler)

  while True:
    if stop == True:
      break
    command = input("git> ")
    if command == "%undo":
      commands.pop()
    elif command == "%run":
      run_commands()
    elif command == "%exit":
      sys.exit(0)
    else:
      commands += [cmd.strip() for cmd in command.split(";")]

  signal.pause()
  readline.set_history_length(-1)
except IOError:
  pass

atexit.register(readline.write_history_file, history_file)

NoGit là một tập lệnh python đơn giản để ngăn chặn sự lặp lại không cần thiết của từ khóa "git".

Tài liệu:

  • các %undolệnh loại bỏ các lệnh cuối cùng từ stack
  • các %runlệnh chạy các lệnh trong ngăn xếp và xóa stack
  • các %exitlệnh đóng CLI mà không làm bất cứ điều gì
  • nhấn ctr+ccũng giống như chạy%run; %exit
  • tập lệnh lưu các lệnh đã được thực thi vào một tệp được gọi git.historytrong cùng thư mục với tập lệnh
  • bạn có thể thêm nhiều lệnh trong một dòng bằng dấu chấm phẩy
  • bạn có thể sử dụng từ khóa gitở đầu lệnh và tập lệnh sẽ không sao chép nó ( EG: git init không trở thành git git init)

Các lệnh ví dụ:

  1. init
  2. add .
  3. stage .
  4. commit -m "inital commit"
  5. %run; %exit

Thông tin bổ sung (cho người dùng Linux):

Nếu bạn muốn, bạn có thể xóa .pytiện ích mở rộng và chuyển đổi nó thành tệp thực thi bằng cách sử dụng:

mv ./git.py ./git
chmod +x ./git

Sau đó, thay vì gọi kịch bản như thế này:

python3 git.py

Thay vào đó, bạn sẽ chạy nó:

./git

Thông tin bổ sung (dành cho người lười biếng):

Nếu bạn lười biếng và không muốn gõ ra ./thì bạn có thể di chuyển tập lệnh này vào /bin/thư mục của mình và tạo bí danh cho nó.

Nếu bạn thực sự, thực sự lười biếng, hãy sử dụng các lệnh sau:

sudo cp ./git /bin/nogit
sudo chmod +x /bin/nogit
alias nogit='/bin/nogit'

Nếu bạn thực sự, thực sự, thực sự lười biếng, hãy sao chép và dán một lớp lót sau:

sudo cp ./git /bin/nogit && sudo chmod +x /bin/nogit && alias nogit='/bin/nogit'

Nếu sự lười biếng của bạn đã đạt đến mức mà trước đây loài người chưa biết đến, thì đây là phiên bản nhỏ gọn hơn của cùng một lớp lót:

sudo cp ./git /bin/nogit;sudo chmod +x /bin/nogit;alias nogit='/bin/nogit'

Chúc may mắn.


17

Một cách tiếp cận khác sẽ hoạt động với bất kỳ lệnh nào: sử dụng Ctrl + R (Reverse-i-search).

Tìm kiếm ngược cho phép bạn tìm kiếm lịch sử lệnh của mình. Lặp lại Ctrl + R sau khi nhấn chuỗi tìm kiếm của bạn để lặp lại tìm kiếm trở lại với cùng một chuỗi.

Bạn chỉ cần gõ một lệnh một lần, sau đó bạn có thể nhớ lại lệnh đó từ bất kỳ chuỗi con nào của lệnh. Trong hầu hết các trường hợp, bạn có thể nhớ lại toàn bộ các lệnh rất dài và các biến thể khác nhau của chúng chỉ với hai đến ba chữ cái tìm kiếm được đặt tốt. Không cần cấu hình sẵn ngoài việc sử dụng shell của bạn một cách bình thường và nó tự thích ứng với cách bạn sử dụng shell, chỉ cần gõ lệnh đầy đủ một lần và các lệnh sẽ được tự động thêm vào lịch sử lệnh của bạn.

  • git commit --amend: <Ctrl+R>am
  • git pull: <Ctrl+R>pu
  • git rebase --rebase-merges -i --onto origin/develop origin/develop feature/blue-header: <Ctrl+R>blu
  • git rebase --abort: <Ctrl-R>ab
  • git rebase --continue: <Ctrl-R>con
  • docker-compose stop && git pull && make && docker-compose up -d: <Ctrl-R>up
  • Vân vân

Hơn nữa, Ctrl-R hoạt động không chỉ trên bash, mà rất nhiều chương trình sử dụng thư viện readline (và có rất nhiều trong số chúng), như shell Python, IPython, shell mysql, psql shell, irb (ruby), v.v.


15

Trong ví dụ của bạn, bạn so sánh nó với lời nhắc MySql. Cách thức hoạt động là một quy trình MySql bắt đầu và bạn đưa ra các lệnh của mình cho quy trình đó. Như vậy, tại sao không viết một cái gì đó tương tự trong ngôn ngữ của bạn lựa chọn? Đây là một ví dụ đơn giản trong C ++:

#include <iostream>
#include <cstdlib>

int main(int argc, char *argv[]){
    while(true){
        std::cout << "git> ";
        std::cout.flush();
        std::string command;
        std::getline(std::cin, command);
        if(command == "exit") break;
        std::system("git " + command);
    }

    return 0;
}

Xin lưu ý rằng tôi vừa viết nó từ bộ nhớ và tôi đã không kiểm tra nó bằng trình biên dịch. Có thể có lỗi cú pháp tầm thường.


Chỉ là suy nghĩ của tôi. Bất cứ ai trên Stack Overflow đều có thể tự viết mã chương trình như vậy. Ngôn ngữ lập trình không thực sự quan trọng.
Thomas Weller

@ThomasWeller tôi chắc chắn đồng ý. Tôi đã đăng chương trình để thể hiện chính xác những gì tôi đang nói, không phải vì đây là một chương trình khó viết.
john01dav

9
Bạn sẽ đầu tư nhiều thời gian cho phương pháp này nếu bạn muốn chương trình không có lỗi và có một số lượng lớn các tính năng. Ví dụ: sau khi sửa lỗi xây dựng ban đầu (std :: system () muốn const char *) bạn sẽ nhận thấy rằng có một vòng lặp vô hạn trên EOF. Bạn có thể muốn hỗ trợ lịch sử / đường đọc, hoàn thành tab, một số nội dung để thay đổi thư mục / đặt env vars / shell out / ..., v.v ... Nếu có phần mềm hiện có (như gitsh trong trường hợp này), tại sao không sử dụng nó?
du mục

1
@nomadictype Đó là một lời chỉ trích hợp lệ, nhưng học phần mềm khác cũng là một cam kết về thời gian. Ưu điểm của phương pháp này là chỉ cần một vài phút để nó hoạt động và nó sẽ thực hiện chính xác những gì bạn mong muốn hoặc muốn (có thay đổi).
john01dav

2
Việc mất dòng đọc, chỉnh sửa dòng, hỗ trợ lịch sử, có thể chạy các lệnh đơn giản như ls, v.v ... sẽ khiến bạn tốn nhiều tiền hơn so với bốn tổ hợp phím hoặc do đó bạn đã lưu với điều này.
Nói dối Ryan

13

Đối với những thứ cơ bản, bạn có thể làm:

function ggit(){ while true; do printf 'git> '; read; eval git $REPLY; done }
git> status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    yarn.lock

no changes added to commit (use "git add" and/or "git commit -a")
git> add .
git> status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    yarn.lock

git>

Thoát với ctrl + c


2
Ý tưởng phong nha, tuy nhiên có hai vấn đề. Thứ nhất, ;sau đó dẫn đến bash: syntax error near unexpected token ; '`Thứ hai, evalphần dễ bị tổn thương. Ví dụ, hãy xem xét những gì xảy ra nếu tôi gõ status;cat /etc/passwdvào cái vỏ nhỏ này. Ví dụ vô hại, nhưng bạn có thể biết được điều gì có thể xảy ra. Bạn có thể đơn giản hóa điều đó thành while IFS= read -r -p "git> " gitcmd; do [ "x$gitcmd" != "x" ] && git "$gitcmd";doneĐiều này tất nhiên không phải là bằng chứng đạn, nhưng 1 - nó đơn giản hơn và 2 - tránh thực thi lệnh không git (nhờ vào dấu ngoặc kép). Không lý tưởng, chỉ tốt hơn một chút
Sergiy Kolodyazhnyy

@ Abigail Funny :) Tại sao có, shell chính nó không phải là ứng dụng an toàn nhất. Ngay cả việc trích dẫn một tập tin có thể là một vấn đề. Tuy nhiên, điểm ban đầu tôi đưa ra là chúng ta không thấy trình thông dịch mysql thực thi các lệnh shell, ít nhất là không có systemhoặc \!ít nhất là lúc đầu. Trường hợp giả định có thể là "thay thế" này gitchỉ thực hiện các lệnh, thì thực tế nó cho phép nhiều hơn thế.
Sergiy Kolodyazhnyy

@ Abigail Tôi không sợ, vì tôi biết cái này làm gì. Những người khác không - có thể sẽ phá vỡ thứ gì đó họ không nên. Và một lần nữa - eval không phải là ý tưởng tốt nhất để chạy các lệnh, đặc biệt là khi có đầu vào do người dùng kiểm soát.
Sergiy Kolodyazhnyy

Sửa lỗi đánh máy sau do. Cảm ơn! re: security: Điều này rõ ràng không có nghĩa là được phân phối như một ứng dụng riêng biệt. Chỉ cần đặt vào .bash_profilenếu bạn không thích gõ git. Tôi không quá lo lắng về việc nó "không an toàn". Nếu bạn dán nội dung vào bash mà bạn không hiểu (bao gồm cả tập lệnh oneliner này), bạn sẽ có một khoảng thời gian tồi tệ. Tôi thích điều này bởi vì nó đơn giản, dễ viết và dễ đọc và dễ cải thiện.
Umur Kontacı

2

Khi tôi sử dụng Windows 7 với Conemu, tôi đã thêm phần sau vào tập lệnh khởi động môi trường dev của mình:

doskey g=git $*

Với điều này, tôi chỉ có thể sử dụng glệnh thay vì gõ git. Lần cuối tôi đã thử với Windows 10 và Conemu, nó không hoạt động, tôi nghĩ có một lỗi, nhưng nó đáng để thử.


2

Sử dụng trình chỉnh sửa ngoặc, thật dễ dàng để sử dụng mã và lệnh git của bạn, nó cũng có nhiều tính năng.

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

Ở góc trên bên phải, biểu tượng hai mắt thứ hai được sử dụng để cài đặt các tiện ích mở rộng.

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

Tìm kiếm mở rộng brackets gitnhư hình ảnh trên và cài đặt nó.

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

Một lần nữa ở góc trên cùng bên phải sẽ hiển thị biểu tượng thứ tư, vì vậy chỉ cần nhấp và xem các thay đổi như hình ảnh trên.

Nếu bạn muốn cài đặt dấu ngoặc, sử dụng các lệnh sau:

sudo add-apt-repository ppa:webupd8team/brackets
sudo apt-get update
sudo apt-get install brackets

Để biết thêm thông tin, bạn có thể đọc: Cách cài đặt Brackets Code Editor trong Ubuntu và Linux Mint trên Ubuntupit .

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.