최근에 "git sparse-checkout" 명령어를 살펴보면서 git version을 좀 따져보았었다.

  - https://www.whatwant.com/entry/sparse-checkout-size

 

"떡 본 김에 제사지낸다"고,

이번 기회에 Git 최신 버전을 사용하기 위한 방법을 살펴보도록 하겠다.

 

 

[ Environment ]

릴리즈된지 좀 오래되긴 했지만,

실무에서 주력으로 사용되는 Ubuntu 20.04 버전을 기준으로 하겠다.

(설마 우리 회사에서만? ^^)

 

❯ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal


❯ uname -a
Linux chani22-VBox 5.15.0-76-generic #83~20.04.1-Ubuntu SMP Wed Jun 21 20:23:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

 

 

[ Default ]

Ubuntu 20.04 설치 후에 "git" 설치는 손쉽게 가능하다.

버전까지 바로 확인해보자.

 

❯ sudo apt install git


❯ git --version
git version 2.25.1

 

 

[ Check ]

그러면, 지금 현재 git 최신 버전은 어떻게 될까?

공식 홈페이지에서 확인되는 최신 버전은 "v2.41.0"이다.

 

https://git-scm.com/

 

최신 버전을 사용하는 것이 중요할까!?

"Release Notes"를 한 번 살펴봐보자.

 

https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.41.0.txt

 

밑으로 스크롤을 내려보면 지난 버전의 Release Note도 확인 가능한데,

뭔가 새로운 명령어나 기존 명령어의 변경 및 개선 사항들이 많이 보인다.

 

즉, 새로운 버전이 필요한 상황이 발생할 수 있는 여지가 많다!

 

 

[ Install ① Using Apt ]

Git PPA를 추가해서 apt를 이용해 Git 최신 버전을 설치해보자.

 

❯ sudo add-apt-repository ppa:git-core/ppa
 The most current stable version of Git for Ubuntu.

For release candidates, go to https://launchpad.net/~git-core/+archive/candidate .
 더 많은 정보: https://launchpad.net/~git-core/+archive/ubuntu/ppa 
[ENTER]을 눌러 진행하거나 Ctrl-c를 눌러 추가하는것을 취소합니다.

기존:1 http://packages.microsoft.com/repos/code stable InRelease
기존:2 https://dl.google.com/linux/chrome/debstable InRelease
...


❯ sudo apt upgrade
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다       
상태 정보를 읽는 중입니다... 완료
업그레이드를 계산하는 중입니다... 완료
다음 패키지를 업그레이드할 것입니다:
  git git-man
2개 업그레이드, 0개 새로 설치, 0개 제거 및 0개 업그레이드 안 함.
9,438 k바이트 아카이브를 받아야 합니다.
이 작업 후 10.1 M바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n] 
받기:1 http://ppa.launchpad.net/git-core/ppa/ubuntu focal/main amd64 git amd64 1:2.41.0-0ppa1~ubuntu20.04.1 [7,325 kB]
받기:2 http://ppa.launchpad.net/git-core/ppa/ubuntu focal/main amd64 git-man all 1:2.41.0-0ppa1~ubuntu20.04.1 [2,113 kB]                                       
내려받기 9,438 k바이트, 소요시간 31초 (302 k바이트/초)                                                                                                         
(데이터베이스 읽는중 ...현재 186326개의 파일과 디렉터리가 설치되어 있습니다.)
Preparing to unpack .../git_1%3a2.41.0-0ppa1~ubuntu20.04.1_amd64.deb ...
Unpacking git (1:2.41.0-0ppa1~ubuntu20.04.1) over (1:2.25.1-1ubuntu3.11) ...
Preparing to unpack .../git-man_1%3a2.41.0-0ppa1~ubuntu20.04.1_all.deb ...
Unpacking git-man (1:2.41.0-0ppa1~ubuntu20.04.1) over (1:2.25.1-1ubuntu3.11) ...
git-man (1:2.41.0-0ppa1~ubuntu20.04.1) 설정하는 중입니다 ...
git (1:2.41.0-0ppa1~ubuntu20.04.1) 설정하는 중입니다 ...
Processing triggers for man-db (2.9.1-1) ...


❯ git --version
git version 2.41.0

 

이걸로 끝이다.

 

이렇게 하면 너무 쉽기에 추천할만한 방법이지만...

간혹 내부망 등의 이슈로 PPA 추가가 어려운 경우가 있으니 다른 방법도 알아보자.

 

 

[ Install ② Source Build ]

좀 번거로울 수도 있지만, 소스코드를 내려 받아서 직접 빌드를 해보자.

 

일단 apt로 설치한 git 패키지를 삭제하자.

 

❯ sudo apt purge git
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다       
상태 정보를 읽는 중입니다... 완료
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
  git-man liberror-perl
'sudo apt autoremove'를 이용하여 제거하십시오.
다음 패키지를 지울 것입니다:
  git*
0개 업그레이드, 0개 새로 설치, 1개 제거 및 0개 업그레이드 안 함.
이 작업 후 46.6 M바이트의 디스크 공간이 비워집니다.
계속 하시겠습니까? [Y/n] 
(데이터베이스 읽는중 ...현재 186489개의 파일과 디렉터리가 설치되어 있습니다.)
git (1:2.41.0-0ppa1~ubuntu20.04.1)를 제거합니다...
(데이터베이스 읽는중 ...현재 185600개의 파일과 디렉터리가 설치되어 있습니다.)
Purging configuration files for git (1:2.41.0-0ppa1~ubuntu20.04.1) ...

 

빌드에 필요한 것들을 미리 설치해두자.

 

❯ sudo apt install dh-autoreconf libcurl4-gnutls-dev libexpat1-dev make gettext libz-dev libssl-dev libghc-zlib-dev asciidoc docbook2x
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다       
상태 정보를 읽는 중입니다... 완료
주의, 'libz-dev' 대신에 'zlib1g-dev' 패키지를 선택합니다
패키지 make는 이미 최신 버전입니다 (4.2.1-1.2).
패키지 libexpat1-dev는 이미 최신 버전입니다 (2.2.9-1ubuntu0.6).
libexpat1-dev 패키지는 수동설치로 지정합니다.
패키지 libssl-dev는 이미 최신 버전입니다 (1.1.1f-1ubuntu2.19).
패키지 zlib1g-dev는 이미 최신 버전입니다 (1:1.2.11.dfsg-2ubuntu1.5).
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
  git-man liberror-perl
'sudo apt autoremove'를 이용하여 제거하십시오.
다음의 추가 패키지가 설치될 것입니다 :
  autoconf automake autopoint autotools-dev debhelper dh-strip-nondeterminism dwz ghc intltool-debian libarchive-cpio-perl libarchive-zip-perl libbsd-dev
  libcroco3 libdebhelper-perl libfile-stripnondeterminism-perl libltdl-dev libmail-sendmail-perl libsigsegv2 libsub-override-perl libsys-hostname-long-perl
  libtool m4 po-debconf
제안하는 패키지:
  autoconf-archive gnu-standards autoconf-doc dh-make gettext-doc libasprintf-dev libgettextpo-dev ghc-prof ghc-doc haskell-doc llvm-6.0 libcurl4-doc
  libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev libghc-zlib-doc libghc-zlib-prof libtool-doc gfortran | fortran95-compiler gcj-jdk m4-doc
  libmail-box-perl
다음 새 패키지를 설치할 것입니다:
  autoconf automake autopoint autotools-dev debhelper dh-autoreconf dh-strip-nondeterminism dwz gettext ghc intltool-debian libarchive-cpio-perl
  libarchive-zip-perl libbsd-dev libcroco3 libcurl4-gnutls-dev libdebhelper-perl libfile-stripnondeterminism-perl libghc-zlib-dev libltdl-dev
  libmail-sendmail-perl libsigsegv2 libsub-override-perl libsys-hostname-long-perl libtool m4 po-debconf
0개 업그레이드, 27개 새로 설치, 0개 제거 및 0개 업그레이드 안 함.
74.8 M바이트 아카이브를 받아야 합니다.
이 작업 후 799 M바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n]

 

소스코드를 내려받을 곳을 확인해보자.

 

https://github.com/git/git

 

오른쪽 하단의 tags를 클릭해보자.

 

https://github.com/git/git/tags

 

소스코드 내려받고, 압축을 해제하자.

 

❯ wget https://github.com/git/git/archive/refs/tags/v2.41.0.tar.gz
--2023-07-12 00:42:52--  https://github.com/git/git/archive/refs/tags/v2.41.0.tar.gz
github.com (github.com) 해석 중... 20.200.245.247
다음으로 연결 중: github.com (github.com)|20.200.245.247|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 302 Found
위치: https://codeload.github.com/git/git/tar.gz/refs/tags/v2.41.0 [따라감]
--2023-07-12 00:42:53--  https://codeload.github.com/git/git/tar.gz/refs/tags/v2.41.0
codeload.github.com (codeload.github.com) 해석 중... 20.200.245.246
다음으로 연결 중: codeload.github.com (codeload.github.com)|20.200.245.246|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 200 OK
길이: 지정하지 않음 [application/x-gzip]
저장 위치: `v2.41.0.tar.gz'

v2.41.0.tar.gz                              [          <=>                                                                   ]  10.30M  5.51MB/s    / 1.9s     

2023-07-12 00:42:55 (5.51 MB/s) - `v2.41.0.tar.gz' 저장함 [10804275]


❯ tar zxvf v2.41.0.tar.gz

 

이제 빌드 진행하면 된다. 어렵지 않다.

 

❯ cd git-2.41.0


❯ make prefix=/usr/local all doc info
GIT_VERSION = 2.41.0
    * new build flags
    CC oss-fuzz/fuzz-commit-graph.o
    CC oss-fuzz/fuzz-pack-headers.o
    CC oss-fuzz/fuzz-pack-idx.o
    CC daemon.o
    * new link flags
    CC common-main.o
    CC abspath.o
    CC add-interactive.o
...


❯ sudo make prefix=/usr/local install install-doc install-html install-info

 

기본 환경 설정은 필수 !!

 

❯ git config --global user.name "whatwant"

❯ git config --global user.email "whatwant@whatwant.com"

 

자동완성 기능을 사용하고 싶다면 추가 설정을 진행하자.

 

bash를 사용하는 경우에는 다음과 같이 하면 된다.

 

 sudo cp ./contrib/completion/git-completion.bash /etc/bash_completion.d/

 

zsh을 사용하는 경우에는 다음과 같이 하자.

 

mkdir ~/.zsh


❯ cp ./contrib/completion/git-completion.bash ~/.zsh/



 cp ./contrib/completion/git-completion.zsh ~/.zsh/_git


nano ~/.zshrc

 

뒷 부분에 다음 라인을 추가하면 된다.

 

fpath=(~/.zsh $fpath)
zstyle ':completion:*:*:git:*' script ~/.zsh/git-completion.bash

 

shell 관련된 사항은 shell에 재진입해야 적용된다.

그게 싫다면 source 하던지...^^

 

 

빌드해서 설치까지 진행하는 과정이 어렵게 느껴질 수도 있지만

직접 버전 선택하고, 환경도 직접 꾸미는 것이 확실한 방법이긴 하다. 화이팅 !!

반응형

구글링을 하다가 우연히 발견한 멋진 제목 하나!

 

"Git 특정 디렉터리만 clone 하기"

 

여러 팀이 하나의 Repository를 사용하는 "Mono-Repo" 방식으로 소스코드를 관리할 때

너무 커져버린 용량으로 인한 어려움이 있을 경우에

이런 제목의 글이 눈에 들어오기 시작한다. ^^

 

 

3개의 팀이 다음 그림과 같이 mono-repo로 개발한다고 해보자.

 

https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

 

 

3개팀에서 각자 개발하는 내용이 하나의 저장소에 모이기 때문에 2가지 이슈가 있다.

 

1. clone 받을 때 용량이 쓸데없이(?) 커서 오래걸린다.

2. 개발할 때 쓸데없는(?) 다른 팀 내용들까지 같이 보인다.

 

 

[ background ]

 

일단 보통의 방법으로 clone을 해보자.

 

❯ git clone git@github.com:whatwant-school/git-sparse.git

'git-sparse'에 복제합니다...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 19 (delta 0), reused 3 (delta 0), pack-reused 16
오브젝트를 받는 중: 100% (19/19), 200.06 MiB | 10.03 MiB/s, 완료.

 

200MB 규모의 Repository이다.

tree 방식으로 디렉토리/파일을 보기 위해 tree 유틸리티 설치 후 사용해봤다.

 

❯ sudo apt install tree

❯ tree ./git-sparse

./git-sparse
├── README.md
├── client
│   ├── client-1.dummy
│   └── client-2.dummy
└── server
    ├── server-1.dummy
    └── server-2.dummy

2 directories, 5 files

 

50MB 크기의 파일 4개로 구성된 Repository다. (테스트를 위해 만든 저장소 ^^)

 

 

 

[ sparse-checkout ]

 

0. environment

- 이하 실습을 진행하는 환경은 다음과 같다.

  . OS : Ubuntu 20.04 LTS

  . Git : v2.25.1

 

1. git

- "sparse-checkout" 명령어는 Git v2.25.0 부터 추가되었다.

- 천만 다행으로 Ubuntu 20.04에서 제공되는 Git 패키지의 버전이 가까스로 0.00.1을 넘겼다 ^^

 

- 과거 Git v1.17.0 부터 "sparse checkout"을 제공했었다! (사이에 "-"가 있고 없고의 차이)

  . 그 때의 명령어 사용법과 차이가 있는데, 많은 웹 포스팅에서 이를 섞어서 설명하고 있다.

 

 

2. 어렵게 clone 받기

- 블로그를 돌아다니다 보면 조금 어렵게(?) 아니 번거롭게(?) clone 받는 방법을 소개하고 있다.

 

❯ git init git-sparse-client
/srv/workspace/git-sparse-client/.git/ 안의 빈 깃 저장소를 다시 초기화했습니다

❯ cd git-sparse-client 

❯ git remote add origin git@github.com:whatwant-school/git-sparse.git 

❯ git sparse-checkout init

❯ git sparse-checkout set /client/

❯ cat .git/info/sparse-checkout 
/client/

❯ git pull origin main  
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 19 (delta 0), reused 3 (delta 0), pack-reused 16
오브젝트 묶음 푸는 중: 100% (19/19), 200.06 MiB | 7.07 MiB/s, 완료.
github.com:whatwant-school/git-sparse URL에서
 * branch            main       -> FETCH_HEAD
 * [새로운 브랜치]   main       -> origin/main

 

으응?!

 

❯ tree ./                  
./
└── client
    ├── client-1.dummy
    └── client-2.dummy

1 directory, 2 files

 

- Work Directory의 내용만 보면 내가 원하는대로 client/ 디렉토리만 존재한다.

- 하지만, clone 받는 용량이 줄어든 것은 아니다.

 

- sparse-checkout 명령어는 work directory를 다루기 위한 명령어이지 전송받는 데이터 용량을 줄여주는 것은 아니다.

- 그렇다면, 위와 같이 어렵게(?) clone을 받을 필요가 없다.

 

 

3. 편하게 sparse-checkout 적용하기

- 일반적인 방법으로 clone을 받고 sparse-checkout을 이용해서 정리하는 것이 훨씬 편하다.

 

❯ git clone git@github.com:whatwant-school/git-sparse.git 
'git-sparse'에 복제합니다...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 19 (delta 0), reused 3 (delta 0), pack-reused 16
오브젝트를 받는 중: 100% (19/19), 200.06 MiB | 9.44 MiB/s, 완료.

❯ cd ./git-sparse       

❯ tree ./
./
├── README.md
├── client
│   ├── client-1.dummy
│   └── client-2.dummy
└── server
    ├── server-1.dummy
    └── server-2.dummy

2 directories, 5 files

❯ git sparse-checkout init

❯ git sparse-checkout set /client/

❯ tree ./                            
./
└── client
    ├── client-1.dummy
    └── client-2.dummy

1 directory, 2 files

 

- 훨씬 간단하지 않은가?! ^^

 

 

4. 결론

- "sparse-checkout"은 전송 용량을 줄이기 위한 것이 아니고,

- 내가 개발하는 내용(파일)만 보면서 개발하기 위한 용도로 사용하는 것이다.

 

 

 

[ --filter=blob:none ]

 

0. background

- 웹서핑을 하다보니, clone을 순식간에 할 수 있다는 옵션을 소개하곤 했다.

 

 

1. clone

- "--filter=blob:none" 옵션을 사용하면 필요한 만큼만 blob를 내려받는다.

❯ git clone --filter=blob:none git@github.com:whatwant-school/git-sparse.git 
'git-sparse'에 복제합니다...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 16 (delta 0), reused 4 (delta 0), pack-reused 12
오브젝트를 받는 중: 100% (16/16), 완료.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 3 (delta 0), reused 1 (delta 0), pack-reused 2
오브젝트를 받는 중: 100% (3/3), 100.03 MiB | 9.65 MiB/s, 완료.
파일을 갱신합니다: 100% (3/3), 완료.

❯ cd git-sparse

❯ du -hs ./
201M ./

❯ tree ./
./
├── README.md
├── client
│   └── client-1.dummy
└── server
    └── server-1.dummy

2 directories, 3 files

 

- 보통의 방식으로 clone 받는 것과 비교해보자.

 

❯ git clone git@github.com:whatwant-school/git-sparse.git 
'git-sparse'에 복제합니다...
remote: Enumerating objects: 21, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 21 (delta 0), reused 5 (delta 0), pack-reused 16
오브젝트를 받는 중: 100% (21/21), 200.06 MiB | 10.29 MiB/s, 완료.

❯ cd git-sparse

❯ du -hs ./                                              
301M ./

❯ tree ./
./
├── README.md
├── client
│   └── client-1.dummy
└── server
    └── server-1.dummy

2 directories, 3 files

 

- 어!? 용량이 차이가 난다! 이건 써볼만한 방법이다!!!

 

 

2. with sparse-checkout and 'no-checkout'

- clone 받을 때 "--no-checkout" 옵션을 넣으면 working directory에 checkout을 하지 않는다

- 이렇게 clone을 받은 후 해당 디렉토리를 들어가면 필요한 일부 blob를 내려받느라 시간이 조금 소요된다.

 

❯ git clone --filter=blob:none --no-checkout git@github.com:whatwant-school/git-sparse.git
'git-sparse-no-checkout'에 복제합니다...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 16 (delta 0), reused 4 (delta 0), pack-reused 12
오브젝트를 받는 중: 100% (16/16), 완료.

❯ cd git-sparse

❯ git sparse-checkout init

❯ git sparse-checkout set /client/

❯ du -hs ./
151M ./

❯ tree ./
./
└── client
    └── client-1.dummy

1 directory, 1 file

 

- 용량이 또 줄었다! ^^

 

 

3. 결론

- clone 받을 때 "--filter=blob:none --no-checkout" 옵션을 추가해서 최소한으로 다운받고,

- 'sparse-checkout' 명령어를 섞어주면 내려받는 전체 용량을 확실히 줄여줄 수 있다.

 

 

 

 

git sparse-checkout 명령어에 대한 자세한 내용은 다음 링크를 참조하기 바란다.

https://git-scm.com/docs/git-sparse-checkout/2.41.0

반응형

최근 SW 개발자들이라면 `Git`이라는 버전관리 도구를 무조건 한 번 이상 사용해봤을 것이다.

 

사실 대부분 회사일로던 개인적인 사유로던 `GitHub` 계정이 이미 있을 것이고

Repository 하나 이상쯤은 만들어봤고, clone도 받아봤을 것이다.

 

`Git` 외에 다른 버전관리 도구들이 다양하게 존재하긴 하지만

일단 `Git`이 SW 개발자의 기본 소양이 되어버렸다는 사실은 그 누구도 부정하지 못할 것이다.

 

 

`StackOverflow Survey 2021` 에서 개발자들의 약 93%가 Git을 사용한다고 답한 것을 보면 확실하다!!!

'22년 Survey에서도 결과를 확인할 수 있으면 좋았을텐데, Git 항목이 2022년에는 빠져서... 아쉽다.

  - https://insights.stackoverflow.com/survey/2021#other-tools

 

 

그러면, 여러 Global 기업들도 모두 Git을 사용할까?!

`결론은 대부분 Git을 사용한다!` 이지만, 지금은 이걸 알아볼 때가 아니니 다음 기회로 넘기기로 하고...

 

Facebook(현 Meta)에서는 어떤 개발환경을 사용하고 있을까!?

  - 버전관리: Mercurial

  - 코드리뷰 및 태스크 관리: Phabricator

 

https://engineering.fb.com/2014/01/07/core-data/scaling-mercurial-at-facebook/

https://secure.phabricator.com/book/phabricator/article/introduction/

 

 

그런데, 위에 있는 링크를 타고 들어가보면 알겠지만,

Meta에서는 Mercurial을 그대로 사용하지 않고 상당히 많은 customizing을 가해서 사용하고 있었다.

 

Mercurial 자체도 Git과의 호환성을 보장하지만,

Meta에서는 특히 Git을 중심에 두고 GitHub 지원도 강화하기 위해 막대한 투자를 했다고 한다.

 

그리고 이렇게 Meta에서 10년 동안 열심히 개발한 버전관리 도구를 "Sapling"이라는 이름으로 공개했다!

  - https://engineering.fb.com/2022/11/15/open-source/sapling-source-control-scalable/

 

 

어떤 도구인지 직접 한 번 설치해 보고 사용해봤다.

개발환경 구성이니만큼 Ubuntu 20.04 환경에서 진행했다.

 

사실 Ububtu 18.04 환경에서 하고자 했으나, Sapling이 Ubuntu 20.04/22.04 버전만 지원한다.

 

 

1. GitHub CLI

  - Sapling에서 GitHub 연결할 수 있도록 하기 위해 GitHub CLI 도구를 설치하자

  - https://cli.github.com/

 

 

  - Ubuntu 환경에서의 설치는 아래 링크에 친절히 나와있다.

  - https://github.com/cli/cli/releases/download/v2.20.2/gh_2.20.2_linux_amd64.deb

 

  - 1회성으로 다운로드 받아서 설치할 수도 있다.

  - https://github.com/cli/cli/releases

 

❯ wget https://github.com/cli/cli/releases/download/v2.20.2/gh_2.20.2_linux_amd64.deb

❯ sudo dpkg --install gh_2.20.2_linux_amd64.deb

❯ gh --version                                             
gh version 2.20.2 (2022-11-15)
https://github.com/cli/cli/releases/tag/v2.20.2

 

  - 인증 정보도 등록하자

❯ gh auth login --git-protocol https

 

 

 

2. Sapling Install

  - 본래 주력으로 사용하고 있는 Ubuntu 18.04에서 테스트 진행하려다 보니... 안타깝게도 18.04는 지원하지 않는다.

  - 빌드를 직접 해보면 될지 모르겠지만, 귀차니즘으로... 그냥 20.04 환경에서 진행했다.

 

  - 설치 과정은 다음 링크를 참조하면 된다.

  - https://sapling-scm.com/docs/introduction/installation#linux

 

❯ wget https://github.com/facebook/sapling/releases/download/0.1.20221118-210929-cfbb68aa/sapling_0.1.20221118-210929-cfbb68aa_amd64.Ubuntu20.04.deb

❯ sudo dpkg --install sapling_0.1.20221118-210929-cfbb68aa_amd64.Ubuntu20.04.deb

❯ sl --version                                                                  
Sapling 0.1.20221118-210929-cfbb68aa

❯ sl config --user ui.username "whatwant <whatwant@gmail.com>"

 

 

3. clone

  - 기본적인 사용법은 git 명령어 체계를 따라가는 것 같다.

❯ sl clone https://github.com/whatwant/whatwant               
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
오브젝트 묶음 푸는 중: 100% (6/6), 15.87 KiB | 7.93 MiB/s, 완료.
https://github.com/whatwant/whatwant URL에서
 * [새로운 레퍼런스] babeb04a267ae7ac642532df70c03517d1ea86ca -> remote/main
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

 

  - 기본적인 모습은 조금 특이하긴 하다.

  - clone을 받았을 때 `.git` 디렉토리가 아니라 `.sl` 디렉토리가 생긴다.

  - `sl` 명령어를 치면 지금 현재 브랜치 정보를 보여준다.

❯ cd whatwant

 ls -al
합계 76
drwxrwxr-x 3 chani22 chani22  4096 11월 24 15:25 .
drwxr-xr-x 3 chani22 chani22  4096 11월 24 15:25 ..
drwxrwxr-x 6 chani22 chani22  4096 11월 24 15:29 .sl
-rw-rw-r-- 1 chani22 chani22   443 11월 24 15:25 README.md
-rw-rw-r-- 1 chani22 chani22 58078 11월 24 15:25 career.md

❯ sl
@  babeb04a2  2021-10-17 04:04  whatwant  remote/main
│  Create career.md
~

 

 

4. commit

  - committ 생성 과정을 살펴보자.

  - `git` 하고 차이는 마지막에 `sl` 명령어를 쳤을 때 나오는 정보 뿐이다.

❯ touch sapling.txt 

❯ sl add .                                     
adding sapling.txt

❯ sl commit -m 'my first commit with Sapling'                 

❯ sl                                         
  @  f63c3b928  6 seconds ago  whatwant
╭─╯  my first commit with Sapling

o  babeb04a2  2021-10-17 04:04  whatwant  remote/main
│  Create career.md
~

 

 

5. web (SmartLog)

  - Sapling은 멋지게도 web 인터페이스를 제공해주는데 ... 그냥 실행하면 에러 나온다.

❯ sl web                                     
ERROR: `node` is required to run Interactive Smartlog, but it was not
found on the $PATH. For information on installing Node.js, see:
https://nodejs.dev/en/learn/how-to-install-nodejs/

 

  - nodejs 설치하자

❯ sudo apt install nodejs npm

❯ nodejs --version                           
v10.19.0

 

  - 이제 다시 web !!

❯ sl web

  - 깔끔하고 예쁘다.

 

 

6. Pull-Request

  - PR 생성도 그냥 명령어 한 줄이면 된다.

❯ sl pr 
pushing 1 to https://github.com/whatwant/whatwant
created new pull request: https://github.com/whatwant/whatwant/pull/1
updated body for https://github.com/whatwant/whatwant/pull/1

 

  - 실제 GitHub에 생성되었는지 확인해보자.

 

 

여기까지 간단한 사용법을 살펴봤는데... 그냥 Git을 사용하는 것과의 큰 차이는 느끼지 못하겠다.

 

Git과의 차이점을 설명해주고는 있다.

  - https://sapling-scm.com/docs/introduction/differences-git

 

Staging Area가 없는 것과 몇 가지 차이가 보이기는 하지만,

사실 대용량 Repository일 때 Sapling의 장점이 돋보일 것 같기는 한데...

 

실제 작업하면서 사용을 해봐야 제대로 느껴볼 수 있을 것 같다.

 

 

이번 포스팅은 그냥 Sapling 맛만 보는 것으로...

 

 

반응형

 

요즘 개발자는 당연하고,

디자이너나 기획자들도 git 사용은 필수인 시대가 되었다.

 

인공지능(머신러닝, 딥러닝) 관련해서

공부를 하려고 해도 `git`을 사용할 수 밖에 없다.

 

아니, 사실 솔직히 말하면 git이라기 보다는 `GitHub.com`을 사용해야 하는 것이지만,

그 기반을 이루고 있는 git은 이제 일반 상식이다.

 

조금만 공부하면 사용할 수 있긴 하지만,

제대로 사용하려면 정말 어렵기만한 도구가 바로 git이다.

 

하지만, 실수를 했을 때 되돌릴 수 있는 방법만 알고 있다면

무서워 할 필요가 없다.

 

그리고, 어려움을 느끼고 있는 우리를 대신해서 욕을 해주고 있는 사이트도 있다 !!!

  - https://ohshitgit.com/ko

 

oh shit git

정겹지 않은가?! 

 

 

 

말이 좀 거칠긴 해도,

설명해주는 내용은 정말 말 그대로 꿀팁이다 !!!

 

 

그런데,

회사에서 보기에는 조금 부담스러울 수도 있다.

 

그런 분들을 위해 정중한 표현을 하고 있는 사이트도 제공을 해준다.

  - https://dangitgit.com/ko

 

dangit

아주 정중하지 않은가?!

 

 

재미로만 느껴질 수도 있겠지만,

내용은 정말로 상당히 괜찮다.

 

각자의 git 생활에 도움이 되기를 기원하며 ...

반응형

 

`git`에 대해서 한창 공부할 때도 있었는데,

요즘엔 쓰던 명령어만 쓰면서 그렇게 지내고 있던 와중에...

 

새로운 명령어(기능?)가 `high-level commands`로 추가되었다는 소식을 듣게 되었다.

 

`v2.23.0` 버전의 릴리스 노트에 `switch / restore` 2개의 새로운 명령어를 소개하고 있다.

  - https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt

 

 

이하 과정은 `Ubuntu 18.04` 환경에서 진행했다.

 

 

1. 설치된 버전 확인

  - 새로운 명령어를 사용해보기 위해서는 `v2.23.0` 이상의 버전이 필요하다.

  - Ubuntu 환경에서 apt 패키지를 통해 설치되어있는 git 버전을 확인해보자.

$ git --version 
git version 2.17.1

 

  - 오래된 버전을 삭제하려면 다음과 같이...

$ sudo apt remove git

$ sudo apt autoremove

 

 

2. 신규 버전 설치 (PPA)

  - 가장 편리한 방법인 PPA 추가해서 apt를 통해서 관리하는 방법이다.

$ sudo add-apt-repository ppa:git-core/ppa

$ sudo apt update

$ sudo apt install git

 

 

3. 신규 버전 설치 (Source)

  - 개인적인 취향으로 좋아하는 방식인 Source Code 빌드해서 사용하기 ^^

    . https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

$ sudo apt-get install dh-autoreconf libcurl4-gnutls-dev libexpat1-dev gettext libssl-dev asciidoc xmlto libz-dev docbook2x install-info

$ cd /srv/install/git

$ wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.33.1.tar.gz

$ tar zxvf git-2.33.1.tar.gz

$ cd git-2.33.1

$ make configure

$ ./configure --prefix=/usr/local

$ make all doc info

$ sudo make install install-doc install-html

 

  - 자동 완성 기능도 설정하자

    . bash

$ sudo cp ./contrib/completion/git-completion.bash /etc/bash_completion.d/

  . zsh

$ mkdir -p ~/.zsh

$ cp ./contrib/completion/git-completion.bash ~/.zsh/
$ cp ./contrib/completion/git-completion.zsh ~/.zsh/_git

$ nano ~/.zshrc
...
zstyle ':completion:*:*:git:*' script ~/.zsh/git-completion.bash
fpath=(~/.zsh $fpath)

autoload -Uz compinit && compinit
$ source ~/.zshrc

 

  - git에서 결과 화면이 전환되는 방식으로 나오는 것이 싫은 경우

$ git config --global pager.branch false

 

 

4. New Command

  - 새로운 명령어 `switch / restore`는 기존 `checkout` 명령어의 일부 기능이 분리된 것이다.

    . `checkout` : Switch branches or restore working tree files

    . `switch` : Switch branches

    . `restore` : Restore working tree files

 

 

5. Before (As-was)

  - 기존에 해왔던 방식을 살펴보자

 

  - git source code를 가지고 알아보겠다. (사이즈가 좀 크지만 그래도 ^^)

$ cd /srv/workspace

$ git clone https://github.com/git/git.git

$ cd git/

  - branch 정보를 살펴보자

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/maint
  remotes/origin/master
  remotes/origin/next
  remotes/origin/seen
  remotes/origin/todo

 

  - local에 `develop` branch를 생성해보자 = local branch 생성 + 현재 작업 branch 변경

$ git checkout -b develop                            
새로 만든 'develop' 브랜치로 전환합니다

$ git branch -a          
* develop
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/maint
  remotes/origin/master
  remotes/origin/next
  remotes/origin/seen
  remotes/origin/todo

  - 다시 `master` branch로 변경해보자

$ git checkout master
'master' 브랜치로 전환합니다
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

$ git branch -a      
  develop
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/maint
  remotes/origin/master
  remotes/origin/next
  remotes/origin/seen
  remotes/origin/todo

  - 파일 하나를 변경하고 staging까지 해보자

$ nano README.md

$ git status   
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋하도록 정하지 않은 변경 사항:
  (무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
  (use "git restore <file>..." to discard changes in working directory)
수정함:        README.md

커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)

git add README.md

git status
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋할 변경 사항:
  (use "git restore --staged ..." to unstage)
수정함:        README.md

  - staged 상태에 있는 파일을 빼내자

$ git reset HEAD README.md
리셋 뒤에 스테이징하지 않은 변경 사항:
M README.md

$ git status
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋하도록 정하지 않은 변경 사항:
  (무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
  (use "git restore <file>..." to discard changes in working directory)
수정함:        README.md

커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)

  - 변경된 파일을 원복 해보자

$ git checkout -- README.md 

$ git status               
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋할 사항 없음, 작업 폴더 깨끗함

 

 

 

6. Now (To-be/is)

  - 이제 새로운 명령어로 위의 과정을 다시 해보자

 

  - `develop-2` branch를 생성하고 이동해보자

$ git switch -c develop-2
새로 만든 'develop-2' 브랜치로 전환합니다

$ git branch -a
  develop
* develop-2
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/maint
  remotes/origin/master
  remotes/origin/next
  remotes/origin/seen
  remotes/origin/todo

  - `master` branch로 이동!

$ git switch master
'master' 브랜치로 전환합니다
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

$ git branch -a
  develop
  develop-2
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/maint
  remotes/origin/master
  remotes/origin/next
  remotes/origin/seen
  remotes/origin/todo

  - 파일 하나 수정

$ nano README.md

$ git status
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋하도록 정하지 않은 변경 사항:
  (무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
  (use "git restore <file>..." to discard changes in working directory)
수정함:        README.md

커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)

git add README.md

git status
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋할 변경 사항:
  (use "git restore --staged ..." to unstage)
수정함:        README.md

  - 파일을 일단 unstaged 상태로~

$ git restore --staged README.md

$ git status
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋하도록 정하지 않은 변경 사항:
  (무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
  (use "git restore <file>..." to discard changes in working directory)
수정함:        README.md

커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)

  - 파일 원복!

$ git restore README.md

$ git status
현재 브랜치 master
브랜치가 'origin/master'에 맞게 업데이트된 상태입니다.

커밋할 사항 없음, 작업 폴더 깨끗함

 

 

지금까지 git에 새롭게 추가된 2개의 명령어 `switch / restore` 에 대해서 살펴보았다.

 

보면 알겠지만 기존에 안되던 새로운 기능이 추가된 것은 아니고

`checkout`에서 했던 기능 中 일부분을 분리해서 구성한 것일뿐이다.

 

기존에 `checkout`을 잘 사용해왔던 분들이라면, "굳이 왜~?"라는 말을 할 수도 있겠으나

처음 git을 접하는 분들이라면 조금 더 직관적인 명령어로 느끼지 않을까라는 생각이 든다.

 

그 동안 너무 git을 멀리해왔던 것 같아서 간만에 포스팅해봤다!

 

 

반응형

'SCM > Git-GitHub' 카테고리의 다른 글

Universe 2021 & GitHub Actions  (0) 2022.01.18
github.dev (Web-IDE)  (1) 2021.11.03
git 설치 (Git 2.33.0, Windows 10)  (0) 2021.10.02
GitHub Copilot 처음 써보기  (0) 2021.07.26
GitHub CLI (GitHub Command line)  (0) 2020.09.20

 

정말 간만에 해보는 git 설치.

거기에다가 windows 10 환경은 정말 정말 오랜만이다.

 

 

1. Homepage

   - 모든 시작은 홈페이지

   - https://git-scm.com/

 

2. Download & Install

   - 홈페이지에서 친절하게 알맞은 아이를 추천해준다.

   - 오른쪽 모니터 화면에 있는 `Download for Windows`를 클릭해서 다운로드 후 설치 진행하자.

   - 잘 모르겠으면 추천하는대로 `Next`를 선택하면 된다 ^^

   - 개인적인 취향으로 기본 에디터를 선택하면 되는데, 저는 `nano`를 좋아하므로... ^^

 

3. Test

   - 잘 설치되었는지 확인해보자.

   - 윈도우즈의 `cmd`를 이용해서 해도 되지만, 이왕이면 `Git Bash`로 한 번 해보자.

   - 시작 메뉴에서 `Git Bash`를 클릭하자.

   - 그리고 실행

$ git --version

 

끝~

반응형

'SCM > Git-GitHub' 카테고리의 다른 글

github.dev (Web-IDE)  (1) 2021.11.03
git switch/restore (git 새로운 명령어)  (1) 2021.10.17
GitHub Copilot 처음 써보기  (0) 2021.07.26
GitHub CLI (GitHub Command line)  (0) 2020.09.20
git clone [bare/mirror] 에 대해서 알아보기  (0) 2020.01.01


옛날 옛날 한 옛날에.... 잠시 궁금했던 git clone 옵션들... [ bare / mirror ]


한 번 테스트 해본다고 마음 먹은지 몇 년만에 갑자기 하고 싶다는 의욕이 불끈! ... 은 거짓말이고

회사 업무 中 [ bare / mirror ]  옵션의 차이에 대한 문의가 있었고

이에 대해서 한 번 살펴보고 싶어졌다!!!


0. clone

    - 일단 무조건 clone 해봤다.

$ git clone git@github.com:tensorflow/tensorflow.git ./tensorflow-normal

Cloning into './tensorflow-normal'...

remote: Enumerating objects: 3, done.

remote: Counting objects: 100% (3/3), done.

remote: Compressing objects: 100% (3/3), done.

remote: Total 796000 (delta 0), reused 3 (delta 0), pack-reused 795997

Receiving objects: 100% (796000/796000), 453.08 MiB | 8.29 MiB/s, done.

Resolving deltas: 100% (643770/643770), done.

Checking out files: 100% (19052/19052), done.


$ du -hs ./tensorflow-normal
690M    ./tensorflow-normal


$ git clone --no-checkout git@github.com:tensorflow/tensorflow.git ./tensorflow-no

Cloning into './tensorflow-no'...

remote: Enumerating objects: 3, done.

remote: Counting objects: 100% (3/3), done.

remote: Compressing objects: 100% (3/3), done.

remote: Total 796000 (delta 0), reused 3 (delta 0), pack-reused 795997

Receiving objects: 100% (796000/796000), 453.51 MiB | 8.85 MiB/s, done.

Resolving deltas: 100% (643732/643732), done.


$ du -hs ./tensorflow-no
475M    ./tensorflow-no


$ git clone --bare git@github.com:tensorflow/tensorflow.git ./tensorflow-bare

Cloning into bare repository './tensorflow-bare'...

remote: Enumerating objects: 3, done.

remote: Counting objects: 100% (3/3), done.

remote: Compressing objects: 100% (3/3), done.

remote: Total 796000 (delta 0), reused 3 (delta 0), pack-reused 795997

Receiving objects: 100% (796000/796000), 455.34 MiB | 8.28 MiB/s, done.

Resolving deltas: 100% (643815/643815), done.


$ du -hs ./tensorflow-bare
477M    ./tensorflow-bare


$ git clone --mirror git@github.com:tensorflow/tensorflow.git ./tensorflow-mirror

Cloning into bare repository './tensorflow-mirror'...

remote: Enumerating objects: 1124, done.

remote: Counting objects: 100% (1124/1124), done.

remote: Compressing objects: 100% (1116/1116), done.

remote: Total 1055983 (delta 805), reused 21 (delta 8), pack-reused 1054859

Receiving objects: 100% (1055983/1055983), 1.09 GiB | 8.69 MiB/s, done.

Resolving deltas: 100% (783532/783532), done.


$ du -hs ./tensorflow-mirror
1.2G    ./tensorflow-mirror



1. 정리

    - 위 내용을 표로 정리하면 아래와 같다.


구분 

 normal

 --no-checkout

--bare 

--mirror 

objects 

796,000 

796,000 

796,000 

1,055,983 

Receiving Size 

453.08 MiB 

453.51 MiB 

455.34 MiB 

1.09 GiB 

du Size 

690 M 

475 M 

477 M 

1.2 G 



2. 도식화

    - 위의 상황을 그림으로 설명해보면 아래와 같다.




3. 설명

    - normal

        . 당연히 commit 이력을 모두 담고 있고, 거기에다가 기본 branch로 설정된 소스코드가 working tree에 존재하게 된다.

    - no-checkout

        . commit 이력을 모두 담고 있고, 아직은 working tree에 소스코드를 넣어놓지는 않은 상태다.

    - bare

        . commit 이력만 담고 있다

    - mirror

        . 일반적인 commit 이력뿐만 아니라, 숨어있는(?) 모든 이력들을 담고 있다.


    # 적고나니 이게 뭔 설명인가 싶네.... ^^



4. 차이점 살펴보기

    - normal vs no-checkout

        . HEAD가 가리키는 기본 branch의 latest commit으로 checkout 했냐/안했냐의 차이만 있다.

        . no-checkout으로 clone 한 뒤에 "git checkout -b master"를 하면 결국 똑같다.


    - normal vs bare

        . bare 옵션으로 clone을 하는 것은 개발을 하고자 하는 용도가 아니다. 그러므로 working tree는 없다.

        . normal clone을 했을 때 ".git" 디렉토리 부분만 있는 것이 bare 옵션이기 때문이다.

$ diff ./tensorflow-bare/config ./tensorflow-normal/.git/config

4c4,5

<       bare = true

---

>       bare = false

>       logallrefupdates = true

6a8,11

>       fetch = +refs/heads/*:refs/remotes/origin/*

> [branch "master"]

>       remote = origin

>       merge = refs/heads/master

        . 위의 차이를 보면 알겠지만, bare 옵션으로 clone을 하게 되면 remote를 바라보지 않는다


    - bare vs mirror

        . mirror 옵션은 현재 서버에 기록된(?) 모든 사항을 전부 가져오게 된다.

$ nano ./tensorflow-mirror/packed-refs

# pack-refs with: peeled fully-peeled sorted

4be56f381cd000e91f79209aaf150636db6fb840 refs/heads/0.6.0

...

45e1e4598d3ebab316bf87df9160656f524af36c refs/heads/master

e1c85596366f3133c797f153dac34e01589a231f refs/pull/10000/head

c2d4f5e964503d17107123e51139aa8bbf27c57c refs/pull/10007/head

29d57e0360306de6bc9021eec4b633e96f3549f5 refs/pull/10008/head

ad9e6a95e53a4407db44e0436fc5318522e832cf refs/pull/10011/head

...

        . bare 옵션의 경우에는 "refs/heads/*" 항목만 보이지만,

        . mirror 옵션의 경우에는 "refs/pull/*" 항목도 보인다.

        . GitHub에서 Pull-Request를 할 때 사용되는 commit들이 기록되는 위치가 바로 "refs/pull/*" 이다.



위의 내용에 대해서 잘 생각해보고 용도에 맞춰서 잘 사용하기 바란다~


반응형


Git 저장소를 오래 운영하다보니

호스팅하고 있는 서버의 스토리지가 부족한 일이 종종 발생한다. (Gerrit 또는 GitHub Enterprise)


(대체 왜 자꾸 바이너리를 올리는 것인지... 우이쒸~!!)



스토리지를 팍팍 늘리면 좋겠지만... 우리는 가난하기에.. ^^



이럴 때 보통 "git gc"를 실행하곤 하는데...

이게 성능/효과가 얼마나 있는지 실험을 해보고 싶었다!!!



0. target


    - 실험할 repo가 필요해서 찾던 中 최근 유명한 tensorflow를 대상으로 정했다.


$ git clone --bare https://github.com/tensorflow/tensorflow.git


    - 저장공간을 줄이는 것에 대한 실험이니만큼 "--bare" 옵션으로 clone 하였다.


$ du -hs ./

455M    ./


    - 기본 저장 공간은 "455M"




1. [ git gc --aggressive ]


    - 가장 기본적으로 사용하는 옵션으로 해봤다. (오래걸렸다)


$ time git gc --aggressive

Counting objects: 769698, done.

Compressing objects: 100% (760700/760700), done.

Writing objects: 100% (769698/769698), done.

Total 769698 (delta 636704), reused 111483 (delta 0)

Checking connectivity: 769698, done.


real    41m45.048s

user    28m54.865s

sys     0m3.769s


$ du -hs ./

243M    ./







2. [ git gc --aggressive --prune=now ]


    - 구글링을 했더니, 안전하게 그리고 확실하게 gc를 하는 방법이라고 되어있는 2단계 실행법이다.

        . reflog는 "git rebase" 같은 작업을 하다가 발생하는 끈 떨어진(?) log들에 대한 정보이다.


$ git reflog expire --expire=now --all


$ time git gc --aggressive --prune=now

Counting objects: 769698, done.

Compressing objects: 100% (760700/760700), done.

Writing objects: 100% (769698/769698), done.

Total 769698 (delta 636704), reused 111483 (delta 0)

Checking connectivity: 769698, done.


real    41m17.315s

user    28m51.873s

sys     0m3.522s


$ du -hs ./

243M    ./






뭐 결론은 2번 방법으로 실행하면 되겠다~!!!

안전한게 짱이지~!!


조금은 실망~


반응형

+ Recent posts