1. window 객체

window 객체는 브라우저 창을 대변하면서 자바스크립트에서 최상단에 존재하는 객체이다.
자바스크립트 코드 어느 곳에서나 항상 접근할 수 있는 객체이기 때문에 전역 객체, Global Object라고 부르고,
어떤 프로퍼티나 메소드를 사용하든 결국 전역 객체 내부의 것이기 때문에 앞에 window.을 생략할 수도 있다.

window.console.log(window);
window.console.log(window.innerWidth);
window.console.log(window.innerHeight);

2. DOM (Document Object Model, 문서 객체 모델)

간단하게 표현하면 웹 페이지(웹 문서)에 나타나는 HTML 문서 전체를 객체로 표현한 것으로 생각하면 되는데, 이때 각 객체를 노드(Node)라는 용어로 표현하고, 태그는 요소 노드, 문자는 텍스트 노드로 구분된다.

console.log(document);

출력되는 화면, DOM을 직접적으로 접근하게 되면 객체가 아니라 DOM에 해당하는 HTML이 출력된다.

자바스크립트에서 사용해봤던 document 객체가 이 웹 문서의 최상단 객체로 진입점의 역할을 한다.
그래서 document 객체를 활용하면 웹 페이지 내부에 무엇이든 수정할 수 있고, 새로운 콘텐츠를 만들 수도 있다.

3. DOM 트리

DOM 트리

HTML의 계층 구조는 DOM에서도 반영되는데 이러한 계층구조를 나무에 비유해서 DOM 트리라고 부른다.
각 노드 간의 관계는 부모, 자식, 형제라는 용어로 표현한다. DOM 트리의 구조를 잘 파악하고 필요한 노드에 좀 더 자유롭게 접근하기 위해서는 관계(부모, 자식, 형제)를 잘 이해하는것이 중요하다.

태그를 표현하는 노드를 요소 노드(Element Node)라고 부르고, 문자를 표현하는 노드를 텍스트 노트(Text Node)라고 부른다. 일반적으로 텍스트 노드들은 요소 노드의 자식 노드가 되고, 따로 자식 노드를 가질 수 없기 때문에 나무의 잎사귀에 비유해서 잎 노드(Leaf Node)라고 한다. 

4. DOM 이동 시 활용 가능한 프로퍼티

프로퍼티 유형 결과
element.children 자식 요소 노드 element의 자식 요소 모음(HTMLCollection)
element.firstElementChild 자식 요소 노드 element의 첫 번째 자식 요소 하나
element.lastElementChild 자식 요소 노드 element의 마지막 자식 요소 하나
element.parentElement 부모 요소 노드 element의 부모 요소 하나
element.previousElementSibling 형제 요소 노드 element의 이전(previous) 혹은 좌측(left)에 있는 요소 하나
element.nextElementSibling 형제 요소 노드 element의 다음(next) 혹은 우측(right)에 있는 요소 하나
node.childNodes 자식 노드 node의 자식 노드 모음(NodeList)
node.firstChild 자식 노드 node의 첫 번째 자식 노드 하나
node.lastChild 자식 노드 node의 마지막 자식 노드 하나
node.parentNode 부모 노드 node의 부모 요소 하나
node.previousSibling 형제 노드 node의 이전(previous) 혹은 좌측(left)에 있는 노드 하나
node.nextSibling 형제 노드 node의 다음(next) 혹은 우측(right)에 있는 노드 하나

요소 노드에 대한 이동 프로퍼티  /  모든 노드에 대한 이동 프로퍼티

<body>
  <div id="content">
    <h2 id="title-1">Cat-1</h2>
    <ul id="list-1">
      <li></li>
      <li></li>
      <li></li>
    </ul>
    <h2 id="title-2">Cat-2</h2>
    <ul id="list-2">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </div>
  <script src="index.js"></script>
</body>
//DOM 트리 여행하기
const myTag = document.querySelector('#content');

console.log(myTag);

//자식 요소 노드
console.log(myTag.children); 
console.log(myTag.children[1]);  //자식 요소 노드의 1번째 인덱스에 오는 요소. list-1
console.log(myTag.firstElementChild);  //첫번째 자식 요소. title-1
console.log(myTag.lastElementChild);  //마지막 자식 요소. list-2

//부모 요소 노드
console.log(myTag.parentElement); //body태그가 선택된다.

//형제 요소 노드
console.log(myTag.previousElementSibling); //이전, 좌측에 있는 형제. null
console.log(myTag.nextElementSibling); //다음, 우측에 있는 형제. script

5. 주요 요소 노드 프로퍼티

프로퍼티 내용 참고사항
element.innerHTML 요소 노드 내부의 HTML코드 문자열로 리턴
(줄바꿈이나 들여쓰기, 띄어쓰기도 모두 포함)
요소 안의 정보를 확인할 수도 있지만, 내부의 HTML 자체를 수정할 때 좀 더 자주 활용
element.outerHTML 요소 노드 자체의 전체적인 HTML 코드를 문자열로 리턴 (해당요소 포함)
(줄바꿈이나 들여쓰기, 띄어쓰기도 모두 포함)
outerHTML은 새로운 값을 할당하면 요소 자체가 교체되어 버리기 때문에 주의 (수정X 처음 선택한 요소는 사라진다.)
element.textContent 요소 노드 내부의 내용들 중에서 HTML을 제외하고 텍스트만 리턴 textContent는 말그대로 텍스트만 다루기 때문에 HTML태그를 쓰더라도 모두 텍스트로 처리됨
<body>
  <div id="content">
    <h2 id="title-1">Cat-1</h2>
    <ul id="list-1">
      <li>wonderful</li>
      <li>beautiful</li>
      <li>great</li>
    </ul>
    <h2 id="title-2">Cat-2</h2>
    <ul id="list-2">
      <li>dog</li>
      <li>cat</li>
      <li>monkey</li>
      <li>pig</li>
    </ul>
  </div>
  <script src="index.js"></script>
</body>
//요소 노드 주요 프로퍼티
const myTag = document.querySelector('#list-1');

//innerHTML
console.log(myTag.innerHTML);
myTag.innerHTML = '<li>Exotic</li>';
myTag.innerHTML += '<li>Exotic</li>'; //덧셈 할당 연산자를 통해 기존 HTML 마지막 부분에 추가할 수도 있다.

//outerHTML
console.log(myTag.outerHTML);
myTag.outerHTML = '<ul id="new-list"><li>Exotic</li></ul>';
//수정이 아닌 교체. 처음 선택한 요소는 사라지고 새로 HTML을 만드는 것이다.

//textContext
console.log(myTag.textContext);
myTag.textContext = 'new text!';
//새로운 값을 할당하면 innerHTML과 마찬가지로 내부의 값을 완전히 새로운 값으로 교체

innerHTML 수정 전(좌)과 수정 후(우)

6. 요소 노드 다루기

1. 요소 노드 만들기: document.createElement('태그이름')
2. 요소 노드 꾸미기: element.textContent, element.innerHTML, ...
3. 요소 노드 추가 혹은 이동하기: element.prepend, element.append, element.after, element.before
4. 요소 노드 삭제하기: element.remove()

<body>
  <div>
    <h1>오늘 할 일</h1>
	<ol id="today">
	  <li>자바스크립트 공부</li>
	  <li>고양이 화장실 청소</li>
	  <li>고양이 장난감 쇼핑</li>
	</ol>
	<h1>내일 할 일</h1>
	<ol id="tomorrow">
	  <li>자바스크립트 공부</li>
	  <li>뮤지컬 공연 예매</li>
	  <li>유튜브 시청</li>
	</ol>
  </div>
  <script src="index.js"></script>
</body>
// 요소 노드 추가하기
const tomorrow = document.querySelector('#tomorrow');

// 1. 요소 노드 만들기: document.createElement('태그이름')
const first = document.createElement('li');

// 2. 요소 노드 꾸미기: textContent, innerHTML, ...
first.textContent = '처음';

// 3. 요소 노드 추가하기: NODE.prepend, append, after, before
tomorrow.prepend(first);

const last = document.createElement('li');
last.textContent = '마지막';
tomorrow.append(last);

const last = document.createElement('p');
prev.textContent = '이전';
tomorrow.before('문자열');

const last = document.createElement('p');
next.textContent = '다음';
tomorrow.after(next);
// 노드 삭제와 이동
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');

// 노드 삭제하기: Node.remove()
tomorrow.remove();
today.children[2].remove();

// 노드 이동하기: prepend, append, before, after
today.append(tomorrow.children[1]);
//today에 tomorrow의 1번째 인덱스 자식요소를 가져와줘 (today의 맨마지막에 추가된다.)
tomorrow.children[1].after(today.children[1]);
//tomorrow에 자식요소 1번째 인덱스 뒤에 today 자식요소 1번째 인덱스를 옮겨줘
tomorrow.children[2].before(today.children[1]);
//tomorrow의 자식요소 2번째 인덱스 앞에 today 자식요소 1번째 인덱스를 옮겨줘 
tomorrow.lastElementChild.before(today.children[1]);
//tomorrow의 마지막 자식 요소의 앞에 today 자식요소 1번째 인덱스 가져와줘

7. HTML 속성 다루기

대부분의 HTML 속성은 DOM 객체의 프로퍼티로 변환이 된다. 하지만, 표준 속성이 아닌 경우에는 프로퍼티로 변환이 안 되는데, 아래 메소드를 활용하면 표준이 아닌 HTML 속성들도 다룰 수 있다.

1. 속성에 접근하기: element.getAttribute('속성')
2. 속성 추가(수정)하기: element.setAttribute('속성', '값')
3. 속성 제거하기: element.removeAttribute('속성')

// HTML 속성 (HTML attribute)
const tomorrow = document.querySelector('#tomorrow');
const item = tomorrow.firstElementChild;
const link = item.firstElementChild;

// elem.getAttribute('속성'): 속성에 접근하기
console.log(tomorrow.getAttribute('href'));
console.log(item.getAttribute('class')); //getAttribute를 활용할 때는 class라는 문자열을 그대로 전달

// elem.setAttribute('속성', '값'): 속성 추가(수정)하기
tomorrow.setAttribute('class', 'list'); // 추가
link.setAttribute('href', 'https://www.codeit.kr'); // 수정

// elem.removeAttribute('속성'): 속성 제거하기
tomorrow.removeAttribute('href'); 
tomorrow.removeAttribute('class');

// id 속성
console.log(tomorrow);
console.log(tomorrow.id);

// class 속성
console.log(item);
console.log(item.className); //프로퍼티 이름으로 접근할때는 className이지만

// href 속성
console.log(link);
console.log(link.href);
console.log(tomorrow.href);

8. 스타일 다루기

자바스크립트로 태그의 스타일을 다루는 방법에는 크게 두 가지가 있다.

1. style 프로퍼티 활용하기: element.style.styleName = 'value';
2. class 변경을 통해 간접적으로 스타일 적용하기: element.className, element.classList

‼️style 프로퍼티를 통해서 css 속성을 다룰 때 여러 단어를 이어서 만든 속성은 카멜 표기법을 사용해야한다.

// 스타일 다루기
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');

// style 프로퍼티
today.children[0].style.textDecoration = 'line-through';
today.children[0].style.backgroundColor = '#DDDDDD';
today.children[2].style.textDecoration = 'line-through';
today.children[2].style.backgroundColor = '#DDDDDD';

style 프로퍼티를 활용하면 태그에 직접적으로 적용되어 버리기 때문에 스타일 우선순위가 높아진다는 문제가 있다.
그래서 style 프로퍼티를 사용하는 것보다 태그의 클래스를 변경하는 방식이 조금 더 권장되는 방식이다.

css에 미리 스타일을 지정해두고,

.done {
  opacity: 0.5;
  text-decoration: line-through;
}
// elem.className
today.children[1].className = 'done';

className 프로퍼티에 새로운 값을 할당해서 코드를 실행해보면, done 클래스에 미리 작성해둔 스타일이 입혀지는 방식인 것이다. 다만 한가지 문제는 className 프로퍼티로 값을 변경하게 되면 클래스 속성 값 전체가 바뀌게 된다. 기존에 있던 class는 사라지고 새로 부여한 class만 남는다는 뜻!

하지만 상황에 따라서 기존에 class는 그대로 둔 채로 새로 추가 하고 싶을 수도 있을 것이다. 그럴 때는 classList를 사용하면 된다.

// elem.classList
console.log(today.classList);
console.log(today.children[1].classList);

// elem.classList: add, remove, toggle
const item = tomorrow.children[1];
item.classList.add('done'); //추가
item.classList.remove('done'); //삭제
item.classList.toggle('done'); //있으면 제거, 없으면 추가

//add와 remove는 여러개의 파라미터 값을 줄 수 있다.
item.classList.add('done', 'other');

//toggle은 여러개의 파라미터는 줄 수 없고, 두번 째 파라미터가 boolean형태의 값을 전달 받아서 
//true일 땐 add의 기능만, fales일 땐 remove의 기능만하도록 toggle의 기능을 강제하는 역할을 한다.
item.classList.toggle('done', false);

classList는 클래스의 속성 값을 유사배열로 다루는 프로퍼티이다. 클래스 속성을 하나씩 다룰 수 있는 것 뿐만 아니라 add, remove, toggle이라는 메소드도 활용할 수 있다.

위 코드의 classList 출력(consol.log)값

메소드 내용 참고사항
classList.add 클래스 추가하기 여러 개의 값을 전달하면 여러 클래스 추가 가능
classList.remove 클래스 삭제하기 여러 개의 값을 전달하면 여러 클래스 삭제 가능
classList.toggle 클래스 없으면 추가, 있으면 삭제하기 하나의 값만 적용 가능하고, 두 번째 파라미터로 추가 또는 삭제 기능을 강제할 수 있음

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

자바스크립트 이벤트  (0) 2024.12.14
console.log와 console.dir의 차이  (0) 2024.12.13
이벤트와 클릭  (0) 2024.12.13
태그 선택하기  (0) 2024.12.12
조건문  (0) 2024.01.20

이벤트 : 웹 페이지에서 발생하는 대부분의 일. ex)마우스를 움직이는 일, 클릭, 스크롤, 키보드 입력 등

<body>
  <div>
    <button id="myBtn">Click!</button>
  </div>
</body>
// 이벤트(Event)와 버튼 클릭
const btn = document.querySelector('#myBtn');

// 이벤트 핸들링(Event Handling)
btn.onclick = function() { // 이벤트 핸들러(Event Handler)
  console.log('Hello Codeit!');
};

해당 태그를 변수로 담고, onclick이라는 프로퍼티에 함수를 할당해주면 버튼에 대한 클릭이벤트에 원하는 동작을 할 수 있다.

이벤트 핸들링 : 이벤트가 발생했을 때 어떤 특별한 동작을 하도록 이벤트를 다루는 것

이벤트 핸들러 : 구체적인 동작들을 코드로 표현한 함수 부분

그리고 잘 사용하진 않지만 HTML에서 바로 이벤트 핸들러를 등록 할 수도 있다.

<body>
  <div>
    <button id="myBtn" onclick="console.log('Hello Codeit!')">Click!</button>
  </div>
</body>

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

console.log와 console.dir의 차이  (0) 2024.12.13
객체, 요소, 노드  (1) 2024.12.13
태그 선택하기  (0) 2024.12.12
조건문  (0) 2024.01.20
함수  (0) 2024.01.20

ID로 선택하기

//id로 태그 선택하기
document.getElementById('Id');

ID속성을 통해서 어떤 요소를 가져 오겠다는 뜻이다. id 값을 문자열로 전달해 주게 되면 해당되는 태그가 선택되는 원리이다.

const myTag = document.getElementById('myNumber');
console.log(myTag);

//출력되는 값, HTML에 적혀 있는 태그가 보인다.
<div id="myNumber">0</div>

뿐만 아니라 자식요소가 있는 부모요소를 선택하게 되면 부모태그 요소에 있는 모든 내용들이 표시 되고, 존재하지 않는 태그를 선택하게 되면 null값이 리턴된다.

장점 : 필요한 태그를 명확하게 선택할 수 있다.


Class로 선택하기

//class로 태그 선택하기
document.getElementsByClassName('class');

class는 id와는 다르게 여러 태그에 붙을 수 있어 Element"s"로 작성해야 하니 주의하자.

const myTags = document.getElementsByClassName('color-btn');
console.log(myTags);

출력된 화면

"color-btn" 클래스가 있는 모든 태그들이  대괄호로 감싸져 배열의 형태로 선택됐다. length 프로퍼티도 있어서 배열 같지만, 완벽한 배열은 아니다. 배열을 다룰 때 사용하는 splice나 push 같은 메소드는 사용할 수가 없기 때문에 배열이라고 부르기는 어렵다.

console.log(myTags[1]);
console.log(myTags.length);

for (let tag of myTags) {
  console.log(tag);
}

배열 메소드는 사용할 수 없지만 대괄호 표기법으로 1번 인덱스에 접근한다거나, length 프로퍼티를 활용할 수 있고, for...of 문을 사용하는데에는 아무런 문제가 없다.

+ 여러개의 값을 담고 있는 배열과 형태는 유사하지만 배열의 메소드는 사용할 수 없는 것들을 가리켜서 유사배열(Array-Like Object)이라고 한다.

그리고 클래스가 하나 밖에 없는 값에 접근하려고 하면, 태그가 하나 밖에 없으니 딱 그 태그가 선택될거라고 생각할 수 있다. 확인을 해보면 요소가 한개가 들어있는 HTMLCollection이 출력되기 때문에 그 태그를 선택하려면 [0] 번째 인덱스에 접근 해야 된다.

존재하지 않는 태그를 선택하게 되면 null값이 리턴되던 id 태그 선택과는 다르게 비어있는 HTMLCollection이 출력된다.

console.log(myTags === null); //false, 비어있는 HTMLCollection은 null값과는 다르다.
console.log(myTags.length); //0

+ 여담

유사배열의 특징

  1. 숫자 형태의 indexing이 가능하다. : 유사배열도 배열과 마찬가지로 각 요소에 0부터 시작하는 숫자 형태의 index가 있어야 한다.
  2. length 프로퍼티가 있다. : 숫자 형태의 index가 있더라도 length 프로퍼티가 없다면 유사배열이라기 보다 그냥 숫자 형태의 key로 구성된 일반적인 객체라고 볼 수 있다.
  3. 배열의 기본메소드를 사용할 수 없다. : 인덱싱을 통해 유사배열의 요소에 접근은 쉽지만 수정이나 삭제는 까다롭다. 그래서 내부 요소들은 배열처럼 다룰 수 있으면서 배열의 메소드 사용을 막고싶거나 일반 배열에는 없는 특별한 메소드를 제공하고 싶을 때 유사 배열을 활용한다.
  4. Array.isArray(유사배열)은 false다. : 유사 배열은 배열과 비슷하지만 배열이 아니기 때문에 결과값이 false이다.

태그 이름으로 선택하기

//태그 이름으로 태그 선택하기
document.getElementsByTagName('태그이름');

class와 마찬가지로 Element"s"로 작성해야 하니 주의! 실행결과 역시 class와 똑같이 HTMLCollection을 리턴한다.

const allTags = document.getElementsByTagName('*');

css선택자처럼 '*' 값을 전달하게 되면 모든 태그를 선택할 수도 있다. 하지만 명확한 의도 없이 많은 요소를 한꺼번에 다루면 예상치 못한 실수를 할 수 있으니 주의하자. 많이 사용되는 메소드는 아니다.


CSS 선택자로 선택하기

//css 선택자로 태그 선택하기
document.querySelector('css선택자');

ID 는 #, class는 .을 이용해서 작성할 수 있다.

const myTag = document.querySelector('#myNumber');
console.log(myTag);

const myTag2 = document.getElementById('myNumber');
console.log(myTag2);

위 코드는 같은 값을 출력한다. #과 getElementById는 ID 속성을 가진 태그를 가져온다.

const myTag = document.querySelector('.color-btn');
console.log(myTag);

출력된 화면

HTML Collection과 같은유사배열이 출력될 것 같았지만, color-btn 클래스가 붙어있는 태그들 중에 가장 첫번째 요소(0번째 인덱스)가 선택되었다. 만약 같은 class를 가진 태그 여러개를 가져오고 싶다면 querySelectorAll 메소드를 활용할 수 있다.

const myTags = document.querySelectorAll('.color-btn');
console.log(myTags);

const myTags2 = document.getElementsByClassName('color-btn');
console.log(myTags2);

출력되는 화면

document.querySelectorAll('.color-btn')는 NodeList가 출력됐고, getElementsByClassName('color-btn')는 HTML Collection이 출력됐다. 뭔가 이름은 조금 다르지만 안에 있는 요소는 동일하다.

+존재하지 않는 요소를 선택할 경우 querySelector는 (id 선택과 마찬가지로) null값을, querySelectorAll은 비어있는 NodeList를 리턴한다. 


 

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

객체, 요소, 노드  (1) 2024.12.13
이벤트와 클릭  (0) 2024.12.13
조건문  (0) 2024.01.20
함수  (0) 2024.01.20
예약어  (0) 2024.01.19

HEAD : 어떤 커밋 하나를 가리킴

branch : 하나의 코드 관리 흐름

사실 branch도 HEAD처럼 어떤 커밋 하나를 가리키는 존재이다. (이것을 포인터라고 부른다.)

git에서 커밋은 이전 커밋에 대한 정보를 가지고 있다.

그래서 master(혹은 main) 포인터가 가장 최신의 커밋만 가리키고 있다고 해도 그 이전 커밋으로 하나씩 거슬러 올라갈 수 있기 때문에 어떻게 프로젝트가 변해왔는지 추적할 수 있다.

그래서 branch가 어떤 코드의 관리 흐름이라는 개념이 성립되는 것이다.

HEAD 역시 어떤 커밋을 가리키는 존재로 포인터이다.  HEAD가 가리키는 커밋의 내용대로 워킹 디렉토리의 내용물이 바뀐다. 하지만 정확하게 말하자면 HEAD는 커밋을 직접적으로 가리키지 않는다. HEAD는 branch를 가리킬 뿐이다.

프리미엄이라는 브랜치를 새로 만들고 git checkout premium으로 HEAD를 premium으로 맞춰줬다. 이 상태에서 다른 커밋을 만들면

HEAD가 가리키던 프리미엄 브랜치가 새로운 커밋을 가리킨다. 이 상태에서 마스터 브랜치로 체크아웃하면 HEAD는 다시 master로 이동한다.

그럼 HEAD 입장에선 다섯번째 커밋을 가리키는것이고 다섯번째 커밋의 내용대로 워킹 디렉토리 내용도 변하게 된다.

위 상태에서 또 새로운 커밋을 만들면 커밋 히스토리의 흐름이 갈라진다 (분기한다)

이렇게 쭉 커밋을 하다가 프리미엄 브랜치와 마스터 브랜치를 머지하게 되면 새로운 커밋을 만들어주는데 이 때 커밋을 머지 커밋이라고 한다.

머지의 뜻

 

'코린이 개념잡기 > GIT' 카테고리의 다른 글

Git Flow 브랜치 전략  (0) 2024.12.13
Git branch merge 방법  (0) 2024.12.13
branch  (0) 2024.12.09
커밋 다루기  (0) 2024.12.08
커밋 메시지 작성하기  (1) 2024.12.08

git log 커밋 히스토리를 출력
git log --pretty=oneline --pretty 옵션을 사용하면 커밋 히스토리를 다양한 방식으로 출력할 수 있다. --pretty 옵션에 oneline이라는 값을 주면 커밋 하나당 한 줄씩 출력해준다.
git show [커밋 아이디] 특정 커밋에서 어떤 변경사항이 있었는지 확인
git commit --amend 최신 커밋을 다시 수정해서 새로운 커밋으로 만듦
git config alias.[별명] [커맨드] 길이가 긴 커맨드에 별명을 붙여서 이후로 별명으로 해당 커맨드를 실행할 수 있도록 설정
예시) git config alias.history 'log --pretty=oneline' : git history라고 입력하면 log --pretty=oneline가 실행된다.
git diff [커밋 A의 아이디] [커밋 B의 아이디] 두 커밋 간의 차이 비교
git reset [옵션] [커밋 아이디] 과거 커밋으로 아예 돌아가고 싶을 때
옵션에 따라 하는 작업이 달라진다.(옵션을 생략하면 --mixed 옵션이 적용)
(1) HEAD가 특정 커밋을 가리키도록 이동시킴(--soft는 여기까지 수행)
(2) staging area도 특정 커밋처럼 리셋(--mixed는 여기까지 수행)
(3) working directory도 특정 커밋처럼 리셋(--hard는 여기까지 수행)
그리고 이때 커밋 아이디 대신 HEAD의 위치를 기준으로 한 표기법
(예 : HEAD^ : 현재 HEAD가 가리키고 있는 커밋의 바로 이전 커밋,
HEAD~3 : 현재 HEAD가 가리키는 커밋보다 3단계 전에 있는 커밋)을 사용해도 된다.
git tag [태그 이름] [커밋 아이디]
/ git show [태그이름]
특정 커밋에 태그를 붙임 (보통 프로젝트에서 주요 버전의 시작점이 되는 커밋에 태그를 단다.)
git rest [옵션] eea5 working direcrory staging area repository
--soft 안 바뀜 안 바뀜 HEAD가 eea5 커밋 가리킴
--mixed 안 바뀜 eea5 커밋처럼 바뀜 HEAD가 eea5 커밋 가리킴
--hard eea5 커밋처럼 바뀜 eea5 커밋처럼 바뀜 HEAD가 eea5 커밋 가리킴

git reset 시 옵션들에 대한 설명

** 커밋 아이디는 앞에 4자리 까지만 입력해줘도 괜찮다.
** HEAD  : 어떤 커밋 하나를 가리킨다. 보통 가장 최근에 한 커밋을 가리키고, 매번 더 새로운 커밋을 가리킨다.
** working directory는 HEAD가 가리키는 커밋에 다라 다르게 구성된다.
** HEAD가 최신 커밋보다 더 이전의 커밋을 가리키면 working directory의 내부도 과거 커밋의 모습대로 바뀌게 된다.
**staging area에 있던 것들은 커밋을 하더라도 그것과 상관없이 계속 남아있다.
** --hard 옵션은 별로 권장되진 않는다. 커밋 이후 워킹 디렉토리에서 했던 내용들이 다 사라지고 복구를 할 수 없기 때문이다.

'코린이 개념잡기 > GIT' 카테고리의 다른 글

HEAD와 branch의 관계  (0) 2024.12.09
branch  (0) 2024.12.09
커밋 메시지 작성하기  (1) 2024.12.08
push와 pull  (0) 2024.12.08
staging area에서 파일 제거하기  (0) 2024.12.08

커밋(commit)은 Git에서 가장 핵심적인 개념이다. 커밋은 staging area의 현 상태를 그대로 하나의 버전으로 남기는 작업, 또는 그 결과물을 가리킨다.

커밋에는 크게 다음과 같은 3가지 정보가 있다.

(1) 커밋을 한 사용자 아이디
(2) 커밋한 날짜, 시간
(3) 커밋 메시지

특정 프로젝트 디렉토리가 어떻게 변해왔는지를 한 눈에 잘 파악하기 위해서는 커밋의 이런 정보들이 아주 중요하다. 그런데 (1), (2)는 커밋을 할 때 Git에서 자동으로 기록해주지만, (3) 커밋 메시지는 커밋을 하는 사람이 매번 직접 작성하는 것이기 때문에 사람마다 그 분량이나 스타일이 제각각일 수 있다.

개인 프로젝트의 경우에는 커밋 메시지를 어떻게 작성하든 큰 상관이 없을 수 있지만, 회사에서 여러 명이 참여하는 프로젝트의 경우에는 이 커밋 메시지가 아주 중요하다. 그래서 커밋 메시지를 어떻게 작성해야하는지에 대한 규칙이 정해져있는 경우가 많은데,
그 규칙들은 회사마다 전부 다르다. 그래서 커밋 메시지를 어떻게 작성하면 좋은지에 대한 일반적인 가이드라인이 있다.

1. 커밋 메시지 작성 가이드 라인

  • 커밋 메시지의 제목과 상세 설명 사이에는 한 줄을 비워두기. (git에서 공식적으로 권장하는 사항)
  • 커밋 메시지의 제목 뒤에 온점(.)을 붙이지 말자.
  • 커밋 메시지의 제목의 첫 번째 알파벳은 대문자로 작성해라.
  • 커밋 메시지의 제목은 명령조로 작성해라.(Fix it / Fixed it / Fixes it)
  • 커밋의 상세 내용에는 [①왜 커밋을 했는지 ②어떤 문제가 있었는지 ③적용한 해결책이 어떤 효과를 가져오는지] 를 적으면 좋다.
  • 다른 사람들이 자신의 코드를 바로 이해할 수 있다고 가정하지 말고 최대한 친절하게 적어라.

2. 커밋할 때 알아야할 가이드라인

(1) 하나의 커밋에는 하나의 수정사항, 하나의 이슈(issue)를 해결한 내용만 남기도록 한다.

다양하게 수정을 하고나서 하나의 커밋으로 남기는 것은 좋지 않다. 하나의 커밋이 하나의 사실만을 갖고 있어야 나중에 이해하기 쉽다. 이 말은 결국 최대한 작은 단위의 변화를 기준으로 커밋을 하라는 뜻이다.
어느 정도의 수정사항을 하나의 단위로 볼 것인지는 상황에 따라 조금씩 다를 수 있고, 회사의 규칙에 따라 다를 수도 있다. 어찌 됐든 너무 많은 작업의 결과를 하나의 커밋으로 담지 않아야겠다는 생각을 하면서 커밋을 해야한다.

(2) 현재 프로젝트 디렉토리의 상태가 그 내부의 전체 코드를 실행했을 때 에러가 발생하지 않는 상태인 경우에만 커밋을 하도록 하자. 

커밋으로 보관된 특정 시점의 전체 코드는 항상 문제없이 실행되는 상태여야 한다. 이미 과거의 커밋이 되어버렸다고 우리에게 쓸모없는 커밋이 되는 건 절대 아니기 때문에 과거의 커밋이라도 과거 버전의 프로그램을 사용해야하거나 과거 커밋을 시작점으로 한 다른 방향의 별도 프로젝트를 시작하거나 아예 그 커밋으로 현재 프로젝트를 리셋할 수도 있다.

따라서 매 커밋의 코드들은 항상 정상 실행되는 상태의 코드여야 한다. 그렇지 않으면 나중에 그 커밋을 위와 같은 용도로 사용하려고 할 때 문제가 생길 수 있다. 그리고 협업하는 상황을 생각해봐도 내가 남긴 커밋을 동료 개발자가 실행해봤는데 에러가 나고 실행이 되지 않는다면 좀 민망할 수 있다. 그래서 커밋을 하기 전에 프로그램이 정상 실행되는지 점검하고 커밋하는 것이 좋다.

혹시 가이드라인이 없다고 할지라도 나중에 다시 봤을 때 이해하는데 어려움이 없도록, 다른 동료 개발자와 협업하는 데 방해가 되지 않도록 커밋을 남기고, 그때마다 커밋 메시지를 잘 작성하는 것이 중요하다.

'코린이 개념잡기 > GIT' 카테고리의 다른 글

branch  (0) 2024.12.09
커밋 다루기  (0) 2024.12.08
push와 pull  (0) 2024.12.08
staging area에서 파일 제거하기  (0) 2024.12.08
파일의 4가지 상태  (0) 2024.12.08

$ git push
$ git pull

로컬 레포지토리와 똑같은 내용의 리모트 레포지토리를 사용하는 이유?

1. 안전성

  • 개인 컴퓨터를 분실하거나 문제가 생겼을 때 복원 할 방법이 없다.
  • 이 때 리모트 레포지토리의 내용을 다른 컴퓨터에서 가져오기만 하면 작성하던 내용을 다시 사용할 수 있다.

2. 협업 가능

  • 리모트 레포지토리를 가운데 두고 push와 pull을 이용해 새로운 커밋을 계속 만들어 낼 수 있어 여러 개발자와 협업이 가능해진다.

원칙적으로는 자신의 리모트 레포지토리는 자신만 git push를 할 수 있는데 만약 다른 사용자도 git push를 할 수 있게 해주려면 그 사용자를 해당 리모트 레포지토리의 collaborator로 지정해야한다.

git push -u origin master : 로컬 레포지토리의 내용을 처음으로 리모트 레포지토리에 올릴 때 사용
git push : 로컬 레포지토리의 내용을 리모트 레포지토리에 보내기
git pull : 리모트 레포지토리의 내용을 로컬 레포지토리로 가져오기
git clone [프로젝트의 GitHub 상 주소] : GitHub에 있는 프로젝트를 내 컴퓨터로 가져오기

'코린이 개념잡기 > GIT' 카테고리의 다른 글

커밋 다루기  (0) 2024.12.08
커밋 메시지 작성하기  (1) 2024.12.08
staging area에서 파일 제거하기  (0) 2024.12.08
파일의 4가지 상태  (0) 2024.12.08
git status  (0) 2024.12.08

+ Recent posts